diff --git a/lam/composer.json b/lam/composer.json index 6db00ee13..fcf074a68 100644 --- a/lam/composer.json +++ b/lam/composer.json @@ -3,17 +3,20 @@ "vendor-dir": "lib/3rdParty/composer", "platform": { "php": "8.0.2" + }, + "allow-plugins": { + "php-http/discovery": false } }, "require" : { "web-auth/webauthn-lib" : "3.3.12", "web-auth/cose-lib": "v3.3.12", "web-auth/metadata-service": "3.3.12", - "symfony/http-foundation" : "5.0.7", - "symfony/psr-http-message-bridge" : "1.3.0", + "symfony/http-foundation" : "^6.0", + "symfony/psr-http-message-bridge" : "^2.3", "symfony/http-client": "^5.4", "http-interop/http-factory-guzzle": "^1.2", - "webklex/php-imap" : "^4.1", + "webklex/php-imap" : "^5.5", "phpmailer/phpmailer": "~6.5", "guzzlehttp/psr7": "^1.7", "paragonie/random_compat": "^2.0", diff --git a/lam/composer.lock b/lam/composer.lock index ac2c120b9..72f8af26f 100644 --- a/lam/composer.lock +++ b/lam/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": "03062b5daa34b3cac9e39d30c71c3c99", + "content-hash": "448f15fdfd6995288fbde14aad024974", "packages": [ { "name": "beberlei/assert", @@ -610,16 +610,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.8.1", + "version": "v6.9.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26" + "reference": "f03270e63eaccf3019ef0f32849c497385774e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5dbc8959427416b8ee09a100d7a8588c00fb2e26", - "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/f03270e63eaccf3019ef0f32849c497385774e11", + "reference": "f03270e63eaccf3019ef0f32849c497385774e11", "shasum": "" }, "require": { @@ -667,9 +667,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.8.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.9.0" }, - "time": "2023-07-14T18:33:00+00:00" + "time": "2023-10-05T00:24:42+00:00" }, { "name": "guzzlehttp/psr7", @@ -836,30 +836,31 @@ }, { "name": "illuminate/collections", - "version": "v8.83.27", + "version": "v9.52.16", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" + "reference": "d3710b0b244bfc62c288c1a87eaa62dd28352d1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", + "url": "https://api.github.com/repos/illuminate/collections/zipball/d3710b0b244bfc62c288c1a87eaa62dd28352d1f", + "reference": "d3710b0b244bfc62c288c1a87eaa62dd28352d1f", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "php": "^7.3|^8.0" + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "php": "^8.0.2" }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "autoload": { @@ -886,31 +887,77 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-23T15:29:49+00:00" + "time": "2023-06-11T21:17:10+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v9.52.16", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", + "reference": "bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-02-01T21:42:32+00:00" }, { "name": "illuminate/contracts", - "version": "v8.83.27", + "version": "v9.52.16", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" + "reference": "44f65d723b13823baa02ff69751a5948bde60c22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/44f65d723b13823baa02ff69751a5948bde60c22", + "reference": "44f65d723b13823baa02ff69751a5948bde60c22", "shasum": "" }, "require": { - "php": "^7.3|^8.0", - "psr/container": "^1.0", - "psr/simple-cache": "^1.0" + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "autoload": { @@ -934,29 +981,29 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-13T14:47:47+00:00" + "time": "2023-02-08T14:36:30+00:00" }, { "name": "illuminate/macroable", - "version": "v8.83.27", + "version": "v9.52.16", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "aed81891a6e046fdee72edd497f822190f61c162" + "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", - "reference": "aed81891a6e046fdee72edd497f822190f61c162", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/e3bfaf6401742a9c6abca61b9b10e998e5b6449a", + "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "autoload": { @@ -980,33 +1027,33 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-11-16T13:57:03+00:00" + "time": "2022-08-09T13:29:29+00:00" }, { "name": "illuminate/pagination", - "version": "v8.83.27", + "version": "v9.52.16", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692" + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pagination/zipball/16fe8dc35f9d18c58a3471469af656a02e9ab692", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/0c913d6af303ae0060d94d74d68d537637f7e6d4", + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "ext-filter": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "autoload": { @@ -1030,48 +1077,51 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-27T13:26:06+00:00" + "time": "2023-02-06T02:52:41+00:00" }, { "name": "illuminate/support", - "version": "v8.83.27", + "version": "v9.52.16", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b" + "reference": "223c608dbca27232df6213f776bfe7bdeec24874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1c79242468d3bbd9a0f7477df34f9647dde2a09b", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b", + "url": "https://api.github.com/repos/illuminate/support/zipball/223c608dbca27232df6213f776bfe7bdeec24874", + "reference": "223c608dbca27232df6213f776bfe7bdeec24874", "shasum": "" }, "require": { - "doctrine/inflector": "^1.4|^2.0", - "ext-json": "*", + "doctrine/inflector": "^2.0", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.53.1", - "php": "^7.3|^8.0", - "voku/portable-ascii": "^1.6.1" + "illuminate/collections": "^9.0", + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "nesbot/carbon": "^2.62.1", + "php": "^8.0.2", + "voku/portable-ascii": "^2.0" }, "conflict": { "tightenco/collect": "<5.5.33" }, "suggest": { - "illuminate/filesystem": "Required to use the composer class (^8.0).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", - "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", - "symfony/process": "Required to use the composer class (^5.4).", - "symfony/var-dumper": "Required to use the dd function (^5.4).", + "illuminate/filesystem": "Required to use the composer class (^9.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^6.0).", + "symfony/uid": "Required to use Str::ulid() (^6.0).", + "symfony/var-dumper": "Required to use the dd function (^6.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "autoload": { @@ -1098,7 +1148,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-09-21T21:30:03+00:00" + "time": "2023-06-11T21:11:53+00:00" }, { "name": "league/uri", @@ -1374,16 +1424,16 @@ }, { "name": "nesbot/carbon", - "version": "2.69.0", + "version": "2.71.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c" + "reference": "98276233188583f2ff845a0f992a235472d9466a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/98276233188583f2ff845a0f992a235472d9466a", + "reference": "98276233188583f2ff845a0f992a235472d9466a", "shasum": "" }, "require": { @@ -1476,7 +1526,7 @@ "type": "tidelift" } ], - "time": "2023-08-03T09:00:52+00:00" + "time": "2023-09-25T11:31:05+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -1759,16 +1809,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.21", + "version": "3.0.23", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1" + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4580645d3fc05c189024eb3b834c6c1e4f0f30a1", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/866cc78fbd82462ffd880e3f65692afe928bed50", + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50", "shasum": "" }, "require": { @@ -1849,7 +1899,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.21" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.23" }, "funding": [ { @@ -1865,7 +1915,7 @@ "type": "tidelift" } ], - "time": "2023-07-09T15:24:48+00:00" + "time": "2023-09-18T17:22:01+00:00" }, { "name": "psr/clock", @@ -1917,22 +1967,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1959,22 +2014,22 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -2011,9 +2066,9 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", @@ -2473,25 +2528,23 @@ }, { "name": "ramsey/uuid", - "version": "4.2.3", + "version": "4.7.4", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "60a4c63ab724854332900504274f6150ff26d286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", + "reference": "60a4c63ab724854332900504274f6150ff26d286", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -2503,24 +2556,23 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -2528,9 +2580,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -2555,7 +2604,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.4" }, "funding": [ { @@ -2567,7 +2616,7 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:10:38+00:00" + "time": "2023-04-15T23:01:58+00:00" }, { "name": "spomky-labs/base64url", @@ -2716,25 +2765,25 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -2763,7 +2812,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" }, "funding": [ { @@ -2779,20 +2828,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/http-client", - "version": "v5.4.26", + "version": "v5.4.29", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + "reference": "04784c66cbee613a827363ee1e65db65392893c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", - "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "url": "https://api.github.com/repos/symfony/http-client/zipball/04784c66cbee613a827363ee1e65db65392893c1", + "reference": "04784c66cbee613a827363ee1e65db65392893c1", "shasum": "" }, "require": { @@ -2854,7 +2903,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v5.4.26" + "source": "https://github.com/symfony/http-client/tree/v5.4.29" }, "funding": [ { @@ -2870,7 +2919,7 @@ "type": "tidelift" } ], - "time": "2023-07-03T12:14:50+00:00" + "time": "2023-09-14T20:49:15+00:00" }, { "name": "symfony/http-client-contracts", @@ -2952,116 +3001,39 @@ }, { "name": "symfony/http-foundation", - "version": "v5.0.7", + "version": "v6.0.20", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6" + "reference": "e16b2676a4b3b1fa12378a20b29c364feda2a8d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/26fb006a2c7b6cdd23d52157b05f8414ffa417b6", - "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e16b2676a4b3b1fa12378a20b29c364feda2a8d6", + "reference": "e16b2676a4b3b1fa12378a20b29c364feda2a8d6", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/mime": "^4.4|^5.0", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "^4.4|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "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": "Symfony HttpFoundation Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.0.7" + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.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": "2020-03-30T14:14:32+00:00" - }, - { - "name": "symfony/mime", - "version": "v5.4.26", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "2ea06dfeee20000a319d8407cea1d47533d5a9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/2ea06dfeee20000a319d8407cea1d47533d5a9d2", - "reference": "2ea06dfeee20000a319d8407cea1d47533d5a9d2", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4", - "symfony/serializer": "<5.4.26|>=6,<6.2.13|>=6.3,<6.3.2" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.4.26|~6.2.13|^6.3.2" + "suggest": { + "symfony/mime": "To use the file extension guesser" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Component\\HttpFoundation\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -3081,96 +3053,10 @@ "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/v5.4.26" - }, - "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-07-27T06:29:31+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", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/http-foundation/tree/v6.0.20" }, "funding": [ { @@ -3186,178 +3072,7 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", - "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.28-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.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:30:37+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "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" - } - }, - "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.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" + "time": "2023-01-30T15:41:07+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -3442,82 +3157,6 @@ ], "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", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, { "name": "symfony/polyfill-php73", "version": "v1.28.0", @@ -3823,27 +3462,33 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v1.3.0", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "9d3e80d54d9ae747ad573cad796e8e247df7b796" + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/9d3e80d54d9ae747ad573cad796e8e247df7b796", - "reference": "9d3e80d54d9ae747ad573cad796e8e247df7b796", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e", "shasum": "" }, "require": { - "php": "^7.1", - "psr/http-message": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.0" + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.0" }, "require-dev": { "nyholm/psr7": "^1.1", - "symfony/phpunit-bridge": "^4.4 || ^5.0", - "zendframework/zend-diactoros": "^1.4.1 || ^2.0" + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2" }, "suggest": { "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" @@ -3851,7 +3496,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-main": "2.3-dev" } }, "autoload": { @@ -3886,28 +3531,41 @@ ], "support": { "issues": "https://github.com/symfony/psr-http-message-bridge/issues", - "source": "https://github.com/symfony/psr-http-message-bridge/tree/master" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.3.1" }, - "time": "2019-11-25T19:33:50+00:00" + "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-07-26T11:53:26+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.0.2", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -3918,7 +3576,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -3955,7 +3613,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" }, "funding": [ { @@ -3971,52 +3629,50 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2022-05-30T19:17:58+00:00" }, { "name": "symfony/translation", - "version": "v5.4.24", + "version": "v6.0.19", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "de237e59c5833422342be67402d487fbf50334ff" + "reference": "9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/de237e59c5833422342be67402d487fbf50334ff", - "reference": "de237e59c5833422342be67402d487fbf50334ff", + "url": "https://api.github.com/repos/symfony/translation/zipball/9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", + "reference": "9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.0.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^2.3" + "symfony/translation-contracts": "^2.3|^3.0" }, "conflict": { - "symfony/config": "<4.4", - "symfony/console": "<5.3", - "symfony/dependency-injection": "<5.0", - "symfony/http-kernel": "<5.0", - "symfony/twig-bundle": "<5.0", - "symfony/yaml": "<4.4" + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" }, "provide": { - "symfony/translation-implementation": "2.3" + "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", + "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.0|^6.0", - "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", "symfony/polyfill-intl-icu": "^1.21", "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^4.4|^5.0|^6.0" + "symfony/yaml": "^5.4|^6.0" }, "suggest": { "psr/log-implementation": "To use logging capability in translator", @@ -4052,7 +3708,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.24" + "source": "https://github.com/symfony/translation/tree/v6.0.19" }, "funding": [ { @@ -4068,24 +3724,24 @@ "type": "tidelift" } ], - "time": "2023-05-19T12:34:17+00:00" + "time": "2023-01-01T08:36:10+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.5.2", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=8.0.2" }, "suggest": { "symfony/translation-implementation": "" @@ -4093,7 +3749,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -4130,7 +3786,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.2" }, "funding": [ { @@ -4146,7 +3802,7 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "thecodingmachine/safe", @@ -4289,16 +3945,16 @@ }, { "name": "voku/portable-ascii", - "version": "1.6.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a" + "reference": "b56450eed252f6801410d810c8e1727224ae0743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87337c91b9dfacee02452244ee14ab3c43bc485a", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", "shasum": "" }, "require": { @@ -4335,7 +3991,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/1.6.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" }, "funding": [ { @@ -4359,7 +4015,7 @@ "type": "tidelift" } ], - "time": "2022-01-24T18:55:24+00:00" + "time": "2022-03-08T17:03:00+00:00" }, { "name": "web-auth/cose-lib", @@ -5113,34 +4769,37 @@ }, { "name": "webklex/php-imap", - "version": "4.1.2", + "version": "5.5.0", "source": { "type": "git", "url": "https://github.com/Webklex/php-imap.git", - "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc" + "reference": "3c23c8f66b772ce8597772816e068326559e7e4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Webklex/php-imap/zipball/94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", - "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", + "url": "https://api.github.com/repos/Webklex/php-imap/zipball/3c23c8f66b772ce8597772816e068326559e7e4b", + "reference": "3c23c8f66b772ce8597772816e068326559e7e4b", "shasum": "" }, "require": { "ext-fileinfo": "*", "ext-iconv": "*", "ext-json": "*", + "ext-libxml": "*", "ext-mbstring": "*", "ext-openssl": "*", + "ext-zip": "*", "illuminate/pagination": ">=5.0.0", - "nesbot/carbon": ">=1.0", - "php": ">=7.0.0", + "nesbot/carbon": "^2.62.1", + "php": "^8.0.2", "symfony/http-foundation": ">=2.8.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^9.5.10" }, "suggest": { - "symfony/mime": "Recomended for better extension support" + "symfony/mime": "Recomended for better extension support", + "symfony/var-dumper": "Usefull tool for debugging" }, "type": "library", "extra": { @@ -5175,7 +4834,7 @@ ], "support": { "issues": "https://github.com/Webklex/php-imap/issues", - "source": "https://github.com/Webklex/php-imap/tree/4.1.2" + "source": "https://github.com/Webklex/php-imap/tree/5.5.0" }, "funding": [ { @@ -5187,7 +4846,7 @@ "type": "ko_fi" } ], - "time": "2022-12-14T15:45:15+00:00" + "time": "2023-06-28T01:57:03+00:00" } ], "packages-dev": [], @@ -5199,7 +4858,7 @@ "platform": [], "platform-dev": [], "platform-overrides": { - "php": "7.4" + "php": "8.0.2" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.3.0" } diff --git a/lam/lib/3rdParty/composer/autoload.php b/lam/lib/3rdParty/composer/autoload.php index ef2a85573..e0c1f58bb 100644 --- a/lam/lib/3rdParty/composer/autoload.php +++ b/lam/lib/3rdParty/composer/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInited73ceb9c1bdec18b7c6d09764d1bce5::getLoader(); diff --git a/lam/lib/3rdParty/composer/composer/ClassLoader.php b/lam/lib/3rdParty/composer/composer/ClassLoader.php index 4d989a212..a72151c77 100644 --- a/lam/lib/3rdParty/composer/composer/ClassLoader.php +++ b/lam/lib/3rdParty/composer/composer/ClassLoader.php @@ -42,30 +42,79 @@ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var ?string */ private $vendorDir; // PSR-4 + /** + * @var array[] + * @psalm-var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * @var array[] + * @psalm-var array> + */ private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array + */ private $missingClasses = array(); + + /** @var ?string */ private $apcuPrefix; + /** + * @var self[] + */ private static $registeredLoaders = array(); + /** + * @param ?string $vendorDir + */ public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); } + /** + * @return string[] + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -75,28 +124,47 @@ public function getPrefixes() return array(); } + /** + * @return array[] + * @psalm-return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return array[] + * @psalm-return array + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return array[] + * @psalm-return array + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return string[] Array of classname => path + * @psalm-return array + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap + * + * @return void */ public function addClassMap(array $classMap) { @@ -111,9 +179,11 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { @@ -156,11 +226,13 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { @@ -204,8 +276,10 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -220,10 +294,12 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -243,6 +319,8 @@ public function setPsr4($prefix, $paths) * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -265,6 +343,8 @@ public function getUseIncludePath() * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -285,6 +365,8 @@ public function isClassMapAuthoritative() * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -305,14 +387,18 @@ public function getApcuPrefix() * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); if (null === $this->vendorDir) { - //no-op - } elseif ($prepend) { + return; + } + + if ($prepend) { self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; } else { unset(self::$registeredLoaders[$this->vendorDir]); @@ -322,6 +408,8 @@ public function register($prepend = false) /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { @@ -336,15 +424,18 @@ public function unregister() * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -399,6 +490,11 @@ public static function getRegisteredLoaders() return self::$registeredLoaders; } + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -464,14 +560,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/lam/lib/3rdParty/composer/composer/InstalledVersions.php b/lam/lib/3rdParty/composer/composer/InstalledVersions.php index 00afa2c2b..51e734a77 100644 --- a/lam/lib/3rdParty/composer/composer/InstalledVersions.php +++ b/lam/lib/3rdParty/composer/composer/InstalledVersions.php @@ -18,738 +18,29 @@ /** * This class is copied in every Composer installed project and available to all * - * To require it's presence, you can require `composer-runtime-api ^2.0` + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final */ class InstalledVersions { - private static $installed = array ( - 'root' => - array ( - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'aliases' => - array ( - ), - 'reference' => 'a5e3e8ca158a108608a3b700d53c4be67c7a8ebd', - 'name' => '__root__', - ), - 'versions' => - array ( - '__root__' => - array ( - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'aliases' => - array ( - ), - 'reference' => 'a5e3e8ca158a108608a3b700d53c4be67c7a8ebd', - ), - 'beberlei/assert' => - array ( - 'pretty_version' => 'v3.3.2', - 'version' => '3.3.2.0', - 'aliases' => - array ( - ), - 'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655', - ), - 'brick/math' => - array ( - 'pretty_version' => '0.9.3', - 'version' => '0.9.3.0', - 'aliases' => - array ( - ), - 'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae', - ), - 'christian-riesen/base32' => - array ( - 'pretty_version' => '1.6.0', - 'version' => '1.6.0.0', - 'aliases' => - array ( - ), - 'reference' => '2e82dab3baa008e24a505649b0d583c31d31e894', - ), - 'doctrine/inflector' => - array ( - 'pretty_version' => '2.0.8', - 'version' => '2.0.8.0', - 'aliases' => - array ( - ), - 'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff', - ), - 'duosecurity/duo_universal_php' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '8734a47480d2d2f0539e8ee782675e052025d026', - ), - 'facile-it/php-jose-verifier' => - array ( - 'pretty_version' => '0.3.0', - 'version' => '0.3.0.0', - 'aliases' => - array ( - ), - 'reference' => 'b6a3d17896dec0c3e383c0ae83b7be855b8fd247', - ), - 'facile-it/php-openid-client' => - array ( - 'pretty_version' => '0.2.0', - 'version' => '0.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '8396adf100f32d96f9d943e729eb9608a9e15504', - ), - 'fgrosse/phpasn1' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '42060ed45344789fb9f21f9f1864fc47b9e3507b', - ), - 'firebase/php-jwt' => - array ( - 'pretty_version' => 'v6.8.1', - 'version' => '6.8.1.0', - 'aliases' => - array ( - ), - 'reference' => '5dbc8959427416b8ee09a100d7a8588c00fb2e26', - ), - 'guzzlehttp/psr7' => - array ( - 'pretty_version' => '1.9.1', - 'version' => '1.9.1.0', - 'aliases' => - array ( - ), - 'reference' => 'e4490cabc77465aaee90b20cfc9a770f8c04be6b', - ), - 'http-interop/http-factory-guzzle' => - array ( - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '8f06e92b95405216b237521cc64c804dd44c4a81', - ), - 'illuminate/collections' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '705a4e1ef93cd492c45b9b3e7911cccc990a07f4', - ), - 'illuminate/contracts' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '5e0fd287a1b22a6b346a9f7cd484d8cf0234585d', - ), - 'illuminate/macroable' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => 'aed81891a6e046fdee72edd497f822190f61c162', - ), - 'illuminate/pagination' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '16fe8dc35f9d18c58a3471469af656a02e9ab692', - ), - 'illuminate/support' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '1c79242468d3bbd9a0f7477df34f9647dde2a09b', - ), - 'league/uri' => - array ( - 'pretty_version' => '6.7.2', - 'version' => '6.7.2.0', - 'aliases' => - array ( - ), - 'reference' => 'd3b50812dd51f3fbf176344cc2981db03d10fe06', - ), - 'league/uri-interfaces' => - array ( - 'pretty_version' => '2.3.0', - 'version' => '2.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '00e7e2943f76d8cb50c7dfdc2f6dee356e15e383', - ), - 'monolog/monolog' => - array ( - 'pretty_version' => '2.9.1', - 'version' => '2.9.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f259e2b15fb95494c83f52d3caad003bbf5ffaa1', - ), - 'nesbot/carbon' => - array ( - 'pretty_version' => '2.69.0', - 'version' => '2.69.0.0', - 'aliases' => - array ( - ), - 'reference' => '4308217830e4ca445583a37d1bf4aff4153fa81c', - ), - 'paragonie/constant_time_encoding' => - array ( - 'pretty_version' => 'v2.6.3', - 'version' => '2.6.3.0', - 'aliases' => - array ( - ), - 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', - ), - 'paragonie/random_compat' => - array ( - 'pretty_version' => 'v2.0.21', - 'version' => '2.0.21.0', - 'aliases' => - array ( - ), - 'reference' => '96c132c7f2f7bc3230723b66e89f8f150b29d5ae', - ), - 'php-http/async-client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - ), - ), - 'php-http/client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - ), - ), - 'php-http/discovery' => - array ( - 'pretty_version' => '1.19.1', - 'version' => '1.19.1.0', - 'aliases' => - array ( - ), - 'reference' => '57f3de01d32085fea20865f9b16fb0e69347c39e', - ), - 'phpmailer/phpmailer' => - array ( - 'pretty_version' => 'v6.8.1', - 'version' => '6.8.1.0', - 'aliases' => - array ( - ), - 'reference' => 'e88da8d679acc3824ff231fdc553565b802ac016', - ), - 'phpseclib/phpseclib' => - array ( - 'pretty_version' => '3.0.21', - 'version' => '3.0.21.0', - 'aliases' => - array ( - ), - 'reference' => '4580645d3fc05c189024eb3b834c6c1e4f0f30a1', - ), - 'psr/clock' => - array ( - 'pretty_version' => '1.0.0', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => 'e41a24703d4560fd0acb709162f73b8adfc3aa0d', - ), - 'psr/clock-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/container' => - array ( - 'pretty_version' => '1.1.2', - 'version' => '1.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', - ), - 'psr/http-client' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31', - ), - 'psr/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - 1 => '1.0', - ), - ), - 'psr/http-factory' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', - ), - 'psr/http-factory-implementation' => - array ( - 'provided' => - array ( - 0 => '^1.0', - 1 => '*', - ), - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.1', - 'version' => '1.1.0.0', - 'aliases' => - array ( - ), - 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - 1 => '*', - ), - ), - 'psr/http-server-handler' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4', - ), - 'psr/http-server-middleware' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829', - ), - 'psr/log' => - array ( - 'pretty_version' => '1.1.4', - 'version' => '1.1.4.0', - 'aliases' => - array ( - ), - 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', - ), - 'psr/log-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0.0 || 2.0.0 || 3.0.0', - ), - ), - 'psr/simple-cache' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', - ), - 'ralouphie/getallheaders' => - array ( - 'pretty_version' => '3.0.3', - 'version' => '3.0.3.0', - 'aliases' => - array ( - ), - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', - ), - 'ramsey/collection' => - array ( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', - ), - 'ramsey/uuid' => - array ( - 'pretty_version' => '4.2.3', - 'version' => '4.2.3.0', - 'aliases' => - array ( - ), - 'reference' => 'fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df', - ), - 'rhumsaa/uuid' => - array ( - 'replaced' => - array ( - 0 => '4.2.3', - ), - ), - 'spomky-labs/base64url' => - array ( - 'pretty_version' => 'v2.0.4', - 'version' => '2.0.4.0', - 'aliases' => - array ( - ), - 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d', - ), - 'spomky-labs/cbor-php' => - array ( - 'pretty_version' => 'v2.1.0', - 'version' => '2.1.0.0', - 'aliases' => - array ( - ), - 'reference' => '28e2712cfc0b48fae661a48ffc6896d7abe83684', - ), - 'symfony/deprecation-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', - ), - 'symfony/http-client' => - array ( - 'pretty_version' => 'v5.4.26', - 'version' => '5.4.26.0', - 'aliases' => - array ( - ), - 'reference' => '19d48ef7f38e5057ed1789a503cd3eccef039bce', - ), - 'symfony/http-client-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70', - ), - 'symfony/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '2.4', - ), - ), - 'symfony/http-foundation' => - array ( - 'pretty_version' => 'v5.0.7', - 'version' => '5.0.7.0', - 'aliases' => - array ( - ), - 'reference' => '26fb006a2c7b6cdd23d52157b05f8414ffa417b6', - ), - 'symfony/mime' => - array ( - 'pretty_version' => 'v5.4.26', - 'version' => '5.4.26.0', - 'aliases' => - array ( - ), - 'reference' => '2ea06dfeee20000a319d8407cea1d47533d5a9d2', - ), - 'symfony/polyfill-ctype' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', - ), - 'symfony/polyfill-intl-idn' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d', - ), - 'symfony/polyfill-intl-normalizer' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92', - ), - 'symfony/polyfill-mbstring' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '42292d99c55abe617799667f454222c54c60e229', - ), - 'symfony/polyfill-php72' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179', - ), - 'symfony/polyfill-php73' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5', - ), - 'symfony/polyfill-php80' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', - ), - 'symfony/polyfill-php81' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b', - ), - 'symfony/process' => - array ( - 'pretty_version' => 'v5.4.28', - 'version' => '5.4.28.0', - 'aliases' => - array ( - ), - 'reference' => '45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b', - ), - 'symfony/psr-http-message-bridge' => - array ( - 'pretty_version' => 'v1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '9d3e80d54d9ae747ad573cad796e8e247df7b796', - ), - 'symfony/service-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', - ), - 'symfony/translation' => - array ( - 'pretty_version' => 'v5.4.24', - 'version' => '5.4.24.0', - 'aliases' => - array ( - ), - 'reference' => 'de237e59c5833422342be67402d487fbf50334ff', - ), - 'symfony/translation-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => '136b19dd05cdf0709db6537d058bcab6dd6e2dbe', - ), - 'symfony/translation-implementation' => - array ( - 'provided' => - array ( - 0 => '2.3', - ), - ), - 'thecodingmachine/safe' => - array ( - 'pretty_version' => 'v1.3.3', - 'version' => '1.3.3.0', - 'aliases' => - array ( - ), - 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc', - ), - 'voku/portable-ascii' => - array ( - 'pretty_version' => '1.6.1', - 'version' => '1.6.1.0', - 'aliases' => - array ( - ), - 'reference' => '87337c91b9dfacee02452244ee14ab3c43bc485a', - ), - 'web-auth/cose-lib' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => 'efa6ec2ba4e840bc1316a493973c9916028afeeb', - ), - 'web-auth/metadata-service' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => 'ef40d2b7b68c4964247d13fab52e2fa8dbd65246', - ), - 'web-auth/webauthn-lib' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => '5ef9b21c8e9f8a817e524ac93290d08a9f065b33', - ), - 'web-token/jwt-checker' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '5f31d98155951739e2fae7455e8466ccddd08f50', - ), - 'web-token/jwt-core' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678', - ), - 'web-token/jwt-easy' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '01db23252bb53d4fd36975b55dd58466bab1bb30', - ), - 'web-token/jwt-encryption' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '3b8d67d7c5c013750703e7c27f1001544407bbb2', - ), - 'web-token/jwt-key-mgmt' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '0b116379515700d237b4e5de86879078ccb09d8a', - ), - 'web-token/jwt-signature' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '015b59aaf3b6e8fb9f5bd1338845b7464c7d8103', - ), - 'web-token/jwt-signature-algorithm-rsa' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '513ad90eb5ef1886ff176727a769bda4618141b0', - ), - 'webklex/php-imap' => - array ( - 'pretty_version' => '4.1.2', - 'version' => '4.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '94bf93ae8868ac1e073cfbaef377f0ca1acac2bc', - ), - ), -); + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ private static $installedByVendor = array(); /** @@ -765,7 +56,6 @@ public static function getInstalledPackages() $packages[] = array_keys($installed['versions']); } - if (1 === \count($packages)) { return $packages[0]; } @@ -773,19 +63,42 @@ public static function getInstalledPackages() return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); } + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + /** * Checks whether the given package is installed * * This also returns true if the package name is provided or replaced by another package * * @param string $packageName + * @param bool $includeDevRequirements * @return bool */ - public static function isInstalled($packageName) + public static function isInstalled($packageName, $includeDevRequirements = true) { foreach (self::getInstalled() as $installed) { if (isset($installed['versions'][$packageName])) { - return true; + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; } } @@ -799,15 +112,14 @@ public static function isInstalled($packageName) * * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package * @return bool */ public static function satisfies(VersionParser $parser, $packageName, $constraint) { - $constraint = $parser->parseConstraints($constraint); + $constraint = $parser->parseConstraints((string) $constraint); $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); return $provided->matches($constraint); @@ -912,9 +224,26 @@ public static function getReference($packageName) throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** * @return array - * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]} + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} */ public static function getRootPackage() { @@ -926,14 +255,38 @@ public static function getRootPackage() /** * Returns the raw installed.php data for custom implementations * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list} + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} */ public static function getRawData() { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + return self::$installed; } + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + /** * Lets you reload the static array from another file * @@ -950,7 +303,7 @@ public static function getRawData() * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list} $data + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data */ public static function reload($data) { @@ -960,6 +313,7 @@ public static function reload($data) /** * @return array[] + * @psalm-return list}> */ private static function getInstalled() { @@ -970,17 +324,35 @@ private static function getInstalled() $installed = array(); if (self::$canGetVendors) { - // @phpstan-ignore-next-line foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { - $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } } } } - $installed[] = self::$installed; + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } return $installed; } diff --git a/lam/lib/3rdParty/composer/composer/autoload_classmap.php b/lam/lib/3rdParty/composer/composer/autoload_classmap.php index 4103b57c1..74f628d24 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_classmap.php +++ b/lam/lib/3rdParty/composer/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname(dirname(dirname($vendorDir))); return array( @@ -10,7 +10,6 @@ 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', - 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', diff --git a/lam/lib/3rdParty/composer/composer/autoload_files.php b/lam/lib/3rdParty/composer/composer/autoload_files.php index 0f91b9354..3853cb9c1 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_files.php +++ b/lam/lib/3rdParty/composer/composer/autoload_files.php @@ -2,28 +2,25 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname(dirname(dirname($vendorDir))); return array( - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => $vendorDir . '/beberlei/assert/lib/Assert/functions.php', '60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php', + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', - 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', - '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', - 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c2b3214084883d700175de676a4fc127' => $vendorDir . '/facile-it/php-jose-verifier/src/functions/derived_key.php', '16040cf78e404de30085045d3863ed51' => $vendorDir . '/facile-it/php-jose-verifier/src/functions/jose_secret_key.php', + 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', '51fcf4e06c07cc00c920b44bcd900e7a' => $vendorDir . '/thecodingmachine/safe/deprecated/apc.php', '47f619d9197b36cf5ab70738d7743fe2' => $vendorDir . '/thecodingmachine/safe/deprecated/libevent.php', 'ea6bb8a12ef9b68f6ada99058e530760' => $vendorDir . '/thecodingmachine/safe/deprecated/mssql.php', @@ -113,7 +110,6 @@ '4af1dca6db8c527c6eed27bff85ff0e5' => $vendorDir . '/thecodingmachine/safe/generated/yaz.php', 'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', 'ba61337b858c088ff9f16a5fc3badbeb' => $vendorDir . '/facile-it/php-openid-client/src/functions/base64url_decode.php', 'd4a8a901fd39fc07eb96403508f8f03f' => $vendorDir . '/facile-it/php-openid-client/src/functions/base64url_encode.php', 'c81c91c32460d498a356b65d5a21fc4c' => $vendorDir . '/facile-it/php-openid-client/src/functions/check_server_response.php', diff --git a/lam/lib/3rdParty/composer/composer/autoload_namespaces.php b/lam/lib/3rdParty/composer/composer/autoload_namespaces.php index 9bd4aceed..2e9e6ffd0 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_namespaces.php +++ b/lam/lib/3rdParty/composer/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname(dirname(dirname($vendorDir))); return array( diff --git a/lam/lib/3rdParty/composer/composer/autoload_psr4.php b/lam/lib/3rdParty/composer/composer/autoload_psr4.php index 2af3148ae..7354730b4 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_psr4.php +++ b/lam/lib/3rdParty/composer/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname(dirname(dirname($vendorDir))); return array( @@ -14,17 +14,12 @@ 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), - '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'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'), 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), 'Symfony\\Contracts\\HttpClient\\' => array($vendorDir . '/symfony/http-client-contracts'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), - 'Symfony\\Component\\Mime\\' => array($vendorDir . '/symfony/mime'), 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 'Symfony\\Component\\HttpClient\\' => array($vendorDir . '/symfony/http-client'), 'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'), @@ -49,7 +44,7 @@ 'Jose\\Component\\Encryption\\' => array($vendorDir . '/web-token/jwt-encryption'), 'Jose\\Component\\Core\\' => array($vendorDir . '/web-token/jwt-core'), 'Jose\\Component\\Checker\\' => array($vendorDir . '/web-token/jwt-checker'), - 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'), + 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/support'), 'Illuminate\\Pagination\\' => array($vendorDir . '/illuminate/pagination'), 'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'), 'Http\\Factory\\Guzzle\\' => array($vendorDir . '/http-interop/http-factory-guzzle/src'), diff --git a/lam/lib/3rdParty/composer/composer/autoload_real.php b/lam/lib/3rdParty/composer/composer/autoload_real.php index 84dbc0f67..b72837228 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_real.php +++ b/lam/lib/3rdParty/composer/composer/autoload_real.php @@ -25,51 +25,26 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; spl_autoload_register(array('ComposerAutoloaderInited73ceb9c1bdec18b7c6d09764d1bce5', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); spl_autoload_unregister(array('ComposerAutoloaderInited73ceb9c1bdec18b7c6d09764d1bce5', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5::getInitializer($loader)); - call_user_func(\Composer\Autoload\ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } + $loader->register(true); - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } + $filesToLoad = \Composer\Autoload\ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); + require $file; } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequireed73ceb9c1bdec18b7c6d09764d1bce5($fileIdentifier, $file); + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -function composerRequireed73ceb9c1bdec18b7c6d09764d1bce5($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/lam/lib/3rdParty/composer/composer/autoload_static.php b/lam/lib/3rdParty/composer/composer/autoload_static.php index 7c9a90b71..3e8e566f2 100644 --- a/lam/lib/3rdParty/composer/composer/autoload_static.php +++ b/lam/lib/3rdParty/composer/composer/autoload_static.php @@ -7,24 +7,21 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 { public static $files = array ( - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php', '60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php', + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', - 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', - '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', - 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c2b3214084883d700175de676a4fc127' => __DIR__ . '/..' . '/facile-it/php-jose-verifier/src/functions/derived_key.php', '16040cf78e404de30085045d3863ed51' => __DIR__ . '/..' . '/facile-it/php-jose-verifier/src/functions/jose_secret_key.php', + 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', '51fcf4e06c07cc00c920b44bcd900e7a' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/apc.php', '47f619d9197b36cf5ab70738d7743fe2' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/libevent.php', 'ea6bb8a12ef9b68f6ada99058e530760' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/mssql.php', @@ -114,7 +111,6 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 '4af1dca6db8c527c6eed27bff85ff0e5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/yaz.php', 'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', 'ba61337b858c088ff9f16a5fc3badbeb' => __DIR__ . '/..' . '/facile-it/php-openid-client/src/functions/base64url_decode.php', 'd4a8a901fd39fc07eb96403508f8f03f' => __DIR__ . '/..' . '/facile-it/php-openid-client/src/functions/base64url_encode.php', 'c81c91c32460d498a356b65d5a21fc4c' => __DIR__ . '/..' . '/facile-it/php-openid-client/src/functions/check_server_response.php', @@ -146,17 +142,12 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 'Symfony\\Polyfill\\Php81\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php73\\' => 23, - 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, - 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, - 'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Contracts\\Translation\\' => 30, 'Symfony\\Contracts\\Service\\' => 26, 'Symfony\\Contracts\\HttpClient\\' => 29, 'Symfony\\Component\\Translation\\' => 30, 'Symfony\\Component\\Process\\' => 26, - 'Symfony\\Component\\Mime\\' => 23, 'Symfony\\Component\\HttpFoundation\\' => 33, 'Symfony\\Component\\HttpClient\\' => 29, 'Symfony\\Bridge\\PsrHttpMessage\\' => 30, @@ -275,26 +266,10 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php73', ), - 'Symfony\\Polyfill\\Php72\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', - ), - 'Symfony\\Polyfill\\Intl\\Idn\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), 'Symfony\\Contracts\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation-contracts', @@ -315,10 +290,6 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 array ( 0 => __DIR__ . '/..' . '/symfony/process', ), - 'Symfony\\Component\\Mime\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/mime', - ), 'Symfony\\Component\\HttpFoundation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/http-foundation', @@ -422,9 +393,10 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 ), 'Illuminate\\Support\\' => array ( - 0 => __DIR__ . '/..' . '/illuminate/collections', + 0 => __DIR__ . '/..' . '/illuminate/conditionable', 1 => __DIR__ . '/..' . '/illuminate/macroable', - 2 => __DIR__ . '/..' . '/illuminate/support', + 2 => __DIR__ . '/..' . '/illuminate/collections', + 3 => __DIR__ . '/..' . '/illuminate/support', ), 'Illuminate\\Pagination\\' => array ( @@ -505,7 +477,6 @@ class ComposerStaticInited73ceb9c1bdec18b7c6d09764d1bce5 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', - 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', diff --git a/lam/lib/3rdParty/composer/composer/installed.json b/lam/lib/3rdParty/composer/composer/installed.json index 9fcaa41d6..4139917f6 100644 --- a/lam/lib/3rdParty/composer/composer/installed.json +++ b/lam/lib/3rdParty/composer/composer/installed.json @@ -612,17 +612,17 @@ }, { "name": "firebase/php-jwt", - "version": "v6.8.1", - "version_normalized": "6.8.1.0", + "version": "v6.9.0", + "version_normalized": "6.9.0.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26" + "reference": "f03270e63eaccf3019ef0f32849c497385774e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5dbc8959427416b8ee09a100d7a8588c00fb2e26", - "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/f03270e63eaccf3019ef0f32849c497385774e11", + "reference": "f03270e63eaccf3019ef0f32849c497385774e11", "shasum": "" }, "require": { @@ -640,7 +640,7 @@ "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, - "time": "2023-07-14T18:33:00+00:00", + "time": "2023-10-05T00:24:42+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -672,7 +672,7 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.8.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.9.0" }, "install-path": "../firebase/php-jwt" }, @@ -847,32 +847,33 @@ }, { "name": "illuminate/collections", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" + "reference": "d3710b0b244bfc62c288c1a87eaa62dd28352d1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", + "url": "https://api.github.com/repos/illuminate/collections/zipball/d3710b0b244bfc62c288c1a87eaa62dd28352d1f", + "reference": "d3710b0b244bfc62c288c1a87eaa62dd28352d1f", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "php": "^7.3|^8.0" + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "php": "^8.0.2" }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.0)." }, - "time": "2022-06-23T15:29:49+00:00", + "time": "2023-06-11T21:17:10+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "installation-source": "dist", @@ -902,31 +903,80 @@ }, "install-path": "../illuminate/collections" }, + { + "name": "illuminate/conditionable", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", + "reference": "bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "time": "2023-02-01T21:42:32+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/conditionable" + }, { "name": "illuminate/contracts", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" + "reference": "44f65d723b13823baa02ff69751a5948bde60c22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/44f65d723b13823baa02ff69751a5948bde60c22", + "reference": "44f65d723b13823baa02ff69751a5948bde60c22", "shasum": "" }, "require": { - "php": "^7.3|^8.0", - "psr/container": "^1.0", - "psr/simple-cache": "^1.0" + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, - "time": "2022-01-13T14:47:47+00:00", + "time": "2023-02-08T14:36:30+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "installation-source": "dist", @@ -955,27 +1005,27 @@ }, { "name": "illuminate/macroable", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "aed81891a6e046fdee72edd497f822190f61c162" + "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", - "reference": "aed81891a6e046fdee72edd497f822190f61c162", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/e3bfaf6401742a9c6abca61b9b10e998e5b6449a", + "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.0.2" }, - "time": "2021-11-16T13:57:03+00:00", + "time": "2022-08-09T13:29:29+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "installation-source": "dist", @@ -1004,31 +1054,31 @@ }, { "name": "illuminate/pagination", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692" + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pagination/zipball/16fe8dc35f9d18c58a3471469af656a02e9ab692", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/0c913d6af303ae0060d94d74d68d537637f7e6d4", + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "ext-filter": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" }, - "time": "2022-06-27T13:26:06+00:00", + "time": "2023-02-06T02:52:41+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "installation-source": "dist", @@ -1057,46 +1107,49 @@ }, { "name": "illuminate/support", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.16", + "version_normalized": "9.52.16.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b" + "reference": "223c608dbca27232df6213f776bfe7bdeec24874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1c79242468d3bbd9a0f7477df34f9647dde2a09b", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b", + "url": "https://api.github.com/repos/illuminate/support/zipball/223c608dbca27232df6213f776bfe7bdeec24874", + "reference": "223c608dbca27232df6213f776bfe7bdeec24874", "shasum": "" }, "require": { - "doctrine/inflector": "^1.4|^2.0", - "ext-json": "*", + "doctrine/inflector": "^2.0", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.53.1", - "php": "^7.3|^8.0", - "voku/portable-ascii": "^1.6.1" + "illuminate/collections": "^9.0", + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "nesbot/carbon": "^2.62.1", + "php": "^8.0.2", + "voku/portable-ascii": "^2.0" }, "conflict": { "tightenco/collect": "<5.5.33" }, "suggest": { - "illuminate/filesystem": "Required to use the composer class (^8.0).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", - "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", - "symfony/process": "Required to use the composer class (^5.4).", - "symfony/var-dumper": "Required to use the dd function (^5.4).", + "illuminate/filesystem": "Required to use the composer class (^9.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^6.0).", + "symfony/uid": "Required to use Str::ulid() (^6.0).", + "symfony/var-dumper": "Required to use the dd function (^6.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, - "time": "2022-09-21T21:30:03+00:00", + "time": "2023-06-11T21:11:53+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "installation-source": "dist", @@ -1409,17 +1462,17 @@ }, { "name": "nesbot/carbon", - "version": "2.69.0", - "version_normalized": "2.69.0.0", + "version": "2.71.0", + "version_normalized": "2.71.0.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c" + "reference": "98276233188583f2ff845a0f992a235472d9466a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/98276233188583f2ff845a0f992a235472d9466a", + "reference": "98276233188583f2ff845a0f992a235472d9466a", "shasum": "" }, "require": { @@ -1446,7 +1499,7 @@ "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", "squizlabs/php_codesniffer": "^3.4" }, - "time": "2023-08-03T09:00:52+00:00", + "time": "2023-09-25T11:31:05+00:00", "bin": [ "bin/carbon" ], @@ -1809,17 +1862,17 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.21", - "version_normalized": "3.0.21.0", + "version": "3.0.23", + "version_normalized": "3.0.23.0", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1" + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4580645d3fc05c189024eb3b834c6c1e4f0f30a1", - "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/866cc78fbd82462ffd880e3f65692afe928bed50", + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50", "shasum": "" }, "require": { @@ -1837,7 +1890,7 @@ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." }, - "time": "2023-07-09T15:24:48+00:00", + "time": "2023-09-18T17:22:01+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1902,7 +1955,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.21" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.23" }, "funding": [ { @@ -1973,24 +2026,29 @@ }, { "name": "psr/container", - "version": "1.1.2", - "version_normalized": "1.1.2.0", + "version": "2.0.2", + "version_normalized": "2.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, - "time": "2021-11-05T16:50:12+00:00", + "time": "2021-11-05T16:47:00+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -2018,30 +2076,30 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, "install-path": "../psr/container" }, { "name": "psr/http-client", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "version": "1.0.3", + "version_normalized": "1.0.3.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", "psr/http-message": "^1.0 || ^2.0" }, - "time": "2023-04-10T20:12:12+00:00", + "time": "2023-09-23T14:17:50+00:00", "type": "library", "extra": { "branch-alias": { @@ -2073,7 +2131,7 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, "install-path": "../psr/http-client" }, @@ -2549,26 +2607,24 @@ }, { "name": "ramsey/uuid", - "version": "4.2.3", - "version_normalized": "4.2.3.0", + "version": "4.7.4", + "version_normalized": "4.7.4.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "60a4c63ab724854332900504274f6150ff26d286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", + "reference": "60a4c63ab724854332900504274f6150ff26d286", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -2580,35 +2636,31 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, - "time": "2021-09-25T23:10:38+00:00", + "time": "2023-04-15T23:01:58+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -2634,7 +2686,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.4" }, "funding": [ { @@ -2787,27 +2839,27 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, - "time": "2022-01-02T09:53:40+00:00", + "time": "2022-01-02T09:55:41+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -2837,7 +2889,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" }, "funding": [ { @@ -2857,17 +2909,17 @@ }, { "name": "symfony/http-client", - "version": "v5.4.26", - "version_normalized": "5.4.26.0", + "version": "v5.4.29", + "version_normalized": "5.4.29.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + "reference": "04784c66cbee613a827363ee1e65db65392893c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", - "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "url": "https://api.github.com/repos/symfony/http-client/zipball/04784c66cbee613a827363ee1e65db65392893c1", + "reference": "04784c66cbee613a827363ee1e65db65392893c1", "shasum": "" }, "require": { @@ -2900,7 +2952,7 @@ "symfony/process": "^4.4|^5.0|^6.0", "symfony/stopwatch": "^4.4|^5.0|^6.0" }, - "time": "2023-07-03T12:14:50+00:00", + "time": "2023-09-14T20:49:15+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2931,7 +2983,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v5.4.26" + "source": "https://github.com/symfony/http-client/tree/v5.4.29" }, "funding": [ { @@ -3032,105 +3084,42 @@ }, { "name": "symfony/http-foundation", - "version": "v5.0.7", - "version_normalized": "5.0.7.0", + "version": "v6.0.20", + "version_normalized": "6.0.20.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6" + "reference": "e16b2676a4b3b1fa12378a20b29c364feda2a8d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/26fb006a2c7b6cdd23d52157b05f8414ffa417b6", - "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e16b2676a4b3b1fa12378a20b29c364feda2a8d6", + "reference": "e16b2676a4b3b1fa12378a20b29c364feda2a8d6", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/mime": "^4.4|^5.0", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "^4.4|^5.0" - }, - "time": "2020-03-30T14:14:32+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "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": "Symfony HttpFoundation Component", - "homepage": "https://symfony.com", - "install-path": "../symfony/http-foundation" - }, - { - "name": "symfony/mime", - "version": "v5.4.26", - "version_normalized": "5.4.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "2ea06dfeee20000a319d8407cea1d47533d5a9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/2ea06dfeee20000a319d8407cea1d47533d5a9d2", - "reference": "2ea06dfeee20000a319d8407cea1d47533d5a9d2", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4", - "symfony/serializer": "<5.4.26|>=6,<6.2.13|>=6.3,<6.3.2" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.4.26|~6.2.13|^6.3.2" + "suggest": { + "symfony/mime": "To use the file extension guesser" }, - "time": "2023-07-27T06:29:31+00:00", + "time": "2023-01-30T15:41:07+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Component\\HttpFoundation\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -3150,14 +3139,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Allows manipulating MIME messages", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" - ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.26" + "source": "https://github.com/symfony/http-foundation/tree/v6.0.20" }, "funding": [ { @@ -3173,269 +3158,7 @@ "type": "tidelift" } ], - "install-path": "../symfony/mime" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "version_normalized": "1.28.0.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" - }, - "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\\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" - } - ], - "install-path": "../symfony/polyfill-ctype" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "time": "2023-01-26T09:30:37+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\\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.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-intl-idn" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "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\\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.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-intl-normalizer" + "install-path": "../symfony/http-foundation" }, { "name": "symfony/polyfill-mbstring", @@ -3523,85 +3246,6 @@ ], "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-php73", "version": "v1.28.0", @@ -3919,37 +3563,43 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "version": "v2.3.1", + "version_normalized": "2.3.1.0", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "9d3e80d54d9ae747ad573cad796e8e247df7b796" + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/9d3e80d54d9ae747ad573cad796e8e247df7b796", - "reference": "9d3e80d54d9ae747ad573cad796e8e247df7b796", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e", "shasum": "" }, "require": { - "php": "^7.1", - "psr/http-message": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.0" + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.0" }, "require-dev": { "nyholm/psr7": "^1.1", - "symfony/phpunit-bridge": "^4.4 || ^5.0", - "zendframework/zend-diactoros": "^1.4.1 || ^2.0" + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2" }, "suggest": { "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" }, - "time": "2019-11-25T19:33:50+00:00", + "time": "2023-07-26T11:53:26+00:00", "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-main": "2.3-dev" } }, "installation-source": "dist", @@ -3983,27 +3633,44 @@ "psr-17", "psr-7" ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.3.1" + }, + "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/psr-http-message-bridge" }, { "name": "symfony/service-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.0.2", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -4011,11 +3678,11 @@ "suggest": { "symfony/service-implementation": "" }, - "time": "2022-05-30T19:17:29+00:00", + "time": "2022-05-30T19:17:58+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -4053,7 +3720,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" }, "funding": [ { @@ -4073,56 +3740,54 @@ }, { "name": "symfony/translation", - "version": "v5.4.24", - "version_normalized": "5.4.24.0", + "version": "v6.0.19", + "version_normalized": "6.0.19.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "de237e59c5833422342be67402d487fbf50334ff" + "reference": "9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/de237e59c5833422342be67402d487fbf50334ff", - "reference": "de237e59c5833422342be67402d487fbf50334ff", + "url": "https://api.github.com/repos/symfony/translation/zipball/9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", + "reference": "9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.0.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^2.3" + "symfony/translation-contracts": "^2.3|^3.0" }, "conflict": { - "symfony/config": "<4.4", - "symfony/console": "<5.3", - "symfony/dependency-injection": "<5.0", - "symfony/http-kernel": "<5.0", - "symfony/twig-bundle": "<5.0", - "symfony/yaml": "<4.4" + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" }, "provide": { - "symfony/translation-implementation": "2.3" + "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", + "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.0|^6.0", - "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", "symfony/polyfill-intl-icu": "^1.21", "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^4.4|^5.0|^6.0" + "symfony/yaml": "^5.4|^6.0" }, "suggest": { "psr/log-implementation": "To use logging capability in translator", "symfony/config": "", "symfony/yaml": "" }, - "time": "2023-05-19T12:34:17+00:00", + "time": "2023-01-01T08:36:10+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4153,7 +3818,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.24" + "source": "https://github.com/symfony/translation/tree/v6.0.19" }, "funding": [ { @@ -4173,30 +3838,30 @@ }, { "name": "symfony/translation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=8.0.2" }, "suggest": { "symfony/translation-implementation": "" }, - "time": "2022-06-27T16:58:25+00:00", + "time": "2022-06-27T17:10:44+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -4234,7 +3899,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.2" }, "funding": [ { @@ -4396,17 +4061,17 @@ }, { "name": "voku/portable-ascii", - "version": "1.6.1", - "version_normalized": "1.6.1.0", + "version": "2.0.1", + "version_normalized": "2.0.1.0", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a" + "reference": "b56450eed252f6801410d810c8e1727224ae0743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87337c91b9dfacee02452244ee14ab3c43bc485a", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", "shasum": "" }, "require": { @@ -4418,7 +4083,7 @@ "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" }, - "time": "2022-01-24T18:55:24+00:00", + "time": "2022-03-08T17:03:00+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4445,7 +4110,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/1.6.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" }, "funding": [ { @@ -5189,37 +4854,40 @@ }, { "name": "webklex/php-imap", - "version": "4.1.2", - "version_normalized": "4.1.2.0", + "version": "5.5.0", + "version_normalized": "5.5.0.0", "source": { "type": "git", "url": "https://github.com/Webklex/php-imap.git", - "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc" + "reference": "3c23c8f66b772ce8597772816e068326559e7e4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Webklex/php-imap/zipball/94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", - "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", + "url": "https://api.github.com/repos/Webklex/php-imap/zipball/3c23c8f66b772ce8597772816e068326559e7e4b", + "reference": "3c23c8f66b772ce8597772816e068326559e7e4b", "shasum": "" }, "require": { "ext-fileinfo": "*", "ext-iconv": "*", "ext-json": "*", + "ext-libxml": "*", "ext-mbstring": "*", "ext-openssl": "*", + "ext-zip": "*", "illuminate/pagination": ">=5.0.0", - "nesbot/carbon": ">=1.0", - "php": ">=7.0.0", + "nesbot/carbon": "^2.62.1", + "php": "^8.0.2", "symfony/http-foundation": ">=2.8.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^9.5.10" }, "suggest": { - "symfony/mime": "Recomended for better extension support" + "symfony/mime": "Recomended for better extension support", + "symfony/var-dumper": "Usefull tool for debugging" }, - "time": "2022-12-14T15:45:15+00:00", + "time": "2023-06-28T01:57:03+00:00", "type": "library", "extra": { "branch-alias": { @@ -5254,7 +4922,7 @@ ], "support": { "issues": "https://github.com/Webklex/php-imap/issues", - "source": "https://github.com/Webklex/php-imap/tree/4.1.2" + "source": "https://github.com/Webklex/php-imap/tree/5.5.0" }, "funding": [ { diff --git a/lam/lib/3rdParty/composer/composer/installed.php b/lam/lib/3rdParty/composer/composer/installed.php index bfdf39c6b..c23582ed8 100644 --- a/lam/lib/3rdParty/composer/composer/installed.php +++ b/lam/lib/3rdParty/composer/composer/installed.php @@ -1,727 +1,680 @@ - - array ( - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'aliases' => - array ( + array( + 'name' => '__root__', + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => '2996c1b87d6c1d08920ae01be6288bbd5eb6e2d8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => '2996c1b87d6c1d08920ae01be6288bbd5eb6e2d8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'beberlei/assert' => array( + 'pretty_version' => 'v3.3.2', + 'version' => '3.3.2.0', + 'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655', + 'type' => 'library', + 'install_path' => __DIR__ . '/../beberlei/assert', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'brick/math' => array( + 'pretty_version' => '0.9.3', + 'version' => '0.9.3.0', + 'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae', + 'type' => 'library', + 'install_path' => __DIR__ . '/../brick/math', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'christian-riesen/base32' => array( + 'pretty_version' => '1.6.0', + 'version' => '1.6.0.0', + 'reference' => '2e82dab3baa008e24a505649b0d583c31d31e894', + 'type' => 'library', + 'install_path' => __DIR__ . '/../christian-riesen/base32', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'doctrine/inflector' => array( + 'pretty_version' => '2.0.8', + 'version' => '2.0.8.0', + 'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/inflector', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'duosecurity/duo_universal_php' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '8734a47480d2d2f0539e8ee782675e052025d026', + 'type' => 'library', + 'install_path' => __DIR__ . '/../duosecurity/duo_universal_php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'facile-it/php-jose-verifier' => array( + 'pretty_version' => '0.3.0', + 'version' => '0.3.0.0', + 'reference' => 'b6a3d17896dec0c3e383c0ae83b7be855b8fd247', + 'type' => 'library', + 'install_path' => __DIR__ . '/../facile-it/php-jose-verifier', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'facile-it/php-openid-client' => array( + 'pretty_version' => '0.2.0', + 'version' => '0.2.0.0', + 'reference' => '8396adf100f32d96f9d943e729eb9608a9e15504', + 'type' => 'library', + 'install_path' => __DIR__ . '/../facile-it/php-openid-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'fgrosse/phpasn1' => array( + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'reference' => '42060ed45344789fb9f21f9f1864fc47b9e3507b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../fgrosse/phpasn1', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'firebase/php-jwt' => array( + 'pretty_version' => 'v6.9.0', + 'version' => '6.9.0.0', + 'reference' => 'f03270e63eaccf3019ef0f32849c497385774e11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../firebase/php-jwt', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/psr7' => array( + 'pretty_version' => '1.9.1', + 'version' => '1.9.1.0', + 'reference' => 'e4490cabc77465aaee90b20cfc9a770f8c04be6b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/psr7', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'http-interop/http-factory-guzzle' => array( + 'pretty_version' => '1.2.0', + 'version' => '1.2.0.0', + 'reference' => '8f06e92b95405216b237521cc64c804dd44c4a81', + 'type' => 'library', + 'install_path' => __DIR__ . '/../http-interop/http-factory-guzzle', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/collections' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => 'd3710b0b244bfc62c288c1a87eaa62dd28352d1f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/collections', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/conditionable' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => 'bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/conditionable', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/contracts' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => '44f65d723b13823baa02ff69751a5948bde60c22', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/macroable' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => 'e3bfaf6401742a9c6abca61b9b10e998e5b6449a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/macroable', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/pagination' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => '0c913d6af303ae0060d94d74d68d537637f7e6d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/pagination', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/support' => array( + 'pretty_version' => 'v9.52.16', + 'version' => '9.52.16.0', + 'reference' => '223c608dbca27232df6213f776bfe7bdeec24874', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/support', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'league/uri' => array( + 'pretty_version' => '6.7.2', + 'version' => '6.7.2.0', + 'reference' => 'd3b50812dd51f3fbf176344cc2981db03d10fe06', + 'type' => 'library', + 'install_path' => __DIR__ . '/../league/uri', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'league/uri-interfaces' => array( + 'pretty_version' => '2.3.0', + 'version' => '2.3.0.0', + 'reference' => '00e7e2943f76d8cb50c7dfdc2f6dee356e15e383', + 'type' => 'library', + 'install_path' => __DIR__ . '/../league/uri-interfaces', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'monolog/monolog' => array( + 'pretty_version' => '2.9.1', + 'version' => '2.9.1.0', + 'reference' => 'f259e2b15fb95494c83f52d3caad003bbf5ffaa1', + 'type' => 'library', + 'install_path' => __DIR__ . '/../monolog/monolog', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nesbot/carbon' => array( + 'pretty_version' => '2.71.0', + 'version' => '2.71.0.0', + 'reference' => '98276233188583f2ff845a0f992a235472d9466a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nesbot/carbon', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/constant_time_encoding' => array( + 'pretty_version' => 'v2.6.3', + 'version' => '2.6.3.0', + 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/random_compat' => array( + 'pretty_version' => 'v2.0.21', + 'version' => '2.0.21.0', + 'reference' => '96c132c7f2f7bc3230723b66e89f8f150b29d5ae', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/random_compat', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'php-http/async-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'php-http/client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'php-http/discovery' => array( + 'pretty_version' => '1.19.1', + 'version' => '1.19.1.0', + 'reference' => '57f3de01d32085fea20865f9b16fb0e69347c39e', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/../php-http/discovery', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpmailer/phpmailer' => array( + 'pretty_version' => 'v6.8.1', + 'version' => '6.8.1.0', + 'reference' => 'e88da8d679acc3824ff231fdc553565b802ac016', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpmailer/phpmailer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpseclib/phpseclib' => array( + 'pretty_version' => '3.0.23', + 'version' => '3.0.23.0', + 'reference' => '866cc78fbd82462ffd880e3f65692afe928bed50', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpseclib/phpseclib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/clock' => array( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'reference' => 'e41a24703d4560fd0acb709162f73b8adfc3aa0d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/clock', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/clock-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/container' => array( + 'pretty_version' => '2.0.2', + 'version' => '2.0.2.0', + 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client' => array( + 'pretty_version' => '1.0.3', + 'version' => '1.0.3.0', + 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + 1 => '1.0', + ), + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '^1.0', + 1 => '*', + ), + ), + 'psr/http-message' => array( + 'pretty_version' => '1.1', + 'version' => '1.1.0.0', + 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + 1 => '*', + ), + ), + 'psr/http-server-handler' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-handler', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-server-middleware' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-middleware', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/log-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0.0 || 2.0.0 || 3.0.0', + ), + ), + 'psr/simple-cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/simple-cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ralouphie/getallheaders' => array( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ralouphie/getallheaders', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ramsey/collection' => array( + 'pretty_version' => '1.3.0', + 'version' => '1.3.0.0', + 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ramsey/collection', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ramsey/uuid' => array( + 'pretty_version' => '4.7.4', + 'version' => '4.7.4.0', + 'reference' => '60a4c63ab724854332900504274f6150ff26d286', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ramsey/uuid', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'rhumsaa/uuid' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '4.7.4', + ), + ), + 'spomky-labs/base64url' => array( + 'pretty_version' => 'v2.0.4', + 'version' => '2.0.4.0', + 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../spomky-labs/base64url', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'spomky-labs/cbor-php' => array( + 'pretty_version' => 'v2.1.0', + 'version' => '2.1.0.0', + 'reference' => '28e2712cfc0b48fae661a48ffc6896d7abe83684', + 'type' => 'library', + 'install_path' => __DIR__ . '/../spomky-labs/cbor-php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v3.0.2', + 'version' => '3.0.2.0', + 'reference' => '26954b3d62a6c5fd0ea8a2a00c0353a14978d05c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client' => array( + 'pretty_version' => 'v5.4.29', + 'version' => '5.4.29.0', + 'reference' => '04784c66cbee613a827363ee1e65db65392893c1', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '2.4', + ), + ), + 'symfony/http-foundation' => array( + 'pretty_version' => 'v6.0.20', + 'version' => '6.0.20.0', + 'reference' => 'e16b2676a4b3b1fa12378a20b29c364feda2a8d6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-foundation', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '42292d99c55abe617799667f454222c54c60e229', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php73' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php73', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php81' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php81', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/process' => array( + 'pretty_version' => 'v5.4.28', + 'version' => '5.4.28.0', + 'reference' => '45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/process', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/psr-http-message-bridge' => array( + 'pretty_version' => 'v2.3.1', + 'version' => '2.3.1.0', + 'reference' => '581ca6067eb62640de5ff08ee1ba6850a0ee472e', + 'type' => 'symfony-bridge', + 'install_path' => __DIR__ . '/../symfony/psr-http-message-bridge', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v3.0.2', + 'version' => '3.0.2.0', + 'reference' => 'd78d39c1599bd1188b8e26bb341da52c3c6d8a66', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/translation' => array( + 'pretty_version' => 'v6.0.19', + 'version' => '6.0.19.0', + 'reference' => '9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/translation', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/translation-contracts' => array( + 'pretty_version' => 'v3.0.2', + 'version' => '3.0.2.0', + 'reference' => 'acbfbb274e730e5a0236f619b6168d9dedb3e282', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/translation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/translation-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '2.3|3.0', + ), + ), + 'thecodingmachine/safe' => array( + 'pretty_version' => 'v1.3.3', + 'version' => '1.3.3.0', + 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc', + 'type' => 'library', + 'install_path' => __DIR__ . '/../thecodingmachine/safe', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'voku/portable-ascii' => array( + 'pretty_version' => '2.0.1', + 'version' => '2.0.1.0', + 'reference' => 'b56450eed252f6801410d810c8e1727224ae0743', + 'type' => 'library', + 'install_path' => __DIR__ . '/../voku/portable-ascii', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-auth/cose-lib' => array( + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => 'efa6ec2ba4e840bc1316a493973c9916028afeeb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-auth/cose-lib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-auth/metadata-service' => array( + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => 'ef40d2b7b68c4964247d13fab52e2fa8dbd65246', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-auth/metadata-service', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-auth/webauthn-lib' => array( + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => '5ef9b21c8e9f8a817e524ac93290d08a9f065b33', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-auth/webauthn-lib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-checker' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '5f31d98155951739e2fae7455e8466ccddd08f50', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-checker', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-core' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-core', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-easy' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '01db23252bb53d4fd36975b55dd58466bab1bb30', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-easy', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-encryption' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '3b8d67d7c5c013750703e7c27f1001544407bbb2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-encryption', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-key-mgmt' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '0b116379515700d237b4e5de86879078ccb09d8a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-key-mgmt', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-signature' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '015b59aaf3b6e8fb9f5bd1338845b7464c7d8103', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-signature', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'web-token/jwt-signature-algorithm-rsa' => array( + 'pretty_version' => 'v2.2.11', + 'version' => '2.2.11.0', + 'reference' => '513ad90eb5ef1886ff176727a769bda4618141b0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../web-token/jwt-signature-algorithm-rsa', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'webklex/php-imap' => array( + 'pretty_version' => '5.5.0', + 'version' => '5.5.0.0', + 'reference' => '3c23c8f66b772ce8597772816e068326559e7e4b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../webklex/php-imap', + 'aliases' => array(), + 'dev_requirement' => false, + ), ), - 'reference' => 'a5e3e8ca158a108608a3b700d53c4be67c7a8ebd', - 'name' => '__root__', - ), - 'versions' => - array ( - '__root__' => - array ( - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'aliases' => - array ( - ), - 'reference' => 'a5e3e8ca158a108608a3b700d53c4be67c7a8ebd', - ), - 'beberlei/assert' => - array ( - 'pretty_version' => 'v3.3.2', - 'version' => '3.3.2.0', - 'aliases' => - array ( - ), - 'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655', - ), - 'brick/math' => - array ( - 'pretty_version' => '0.9.3', - 'version' => '0.9.3.0', - 'aliases' => - array ( - ), - 'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae', - ), - 'christian-riesen/base32' => - array ( - 'pretty_version' => '1.6.0', - 'version' => '1.6.0.0', - 'aliases' => - array ( - ), - 'reference' => '2e82dab3baa008e24a505649b0d583c31d31e894', - ), - 'doctrine/inflector' => - array ( - 'pretty_version' => '2.0.8', - 'version' => '2.0.8.0', - 'aliases' => - array ( - ), - 'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff', - ), - 'duosecurity/duo_universal_php' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '8734a47480d2d2f0539e8ee782675e052025d026', - ), - 'facile-it/php-jose-verifier' => - array ( - 'pretty_version' => '0.3.0', - 'version' => '0.3.0.0', - 'aliases' => - array ( - ), - 'reference' => 'b6a3d17896dec0c3e383c0ae83b7be855b8fd247', - ), - 'facile-it/php-openid-client' => - array ( - 'pretty_version' => '0.2.0', - 'version' => '0.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '8396adf100f32d96f9d943e729eb9608a9e15504', - ), - 'fgrosse/phpasn1' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '42060ed45344789fb9f21f9f1864fc47b9e3507b', - ), - 'firebase/php-jwt' => - array ( - 'pretty_version' => 'v6.8.1', - 'version' => '6.8.1.0', - 'aliases' => - array ( - ), - 'reference' => '5dbc8959427416b8ee09a100d7a8588c00fb2e26', - ), - 'guzzlehttp/psr7' => - array ( - 'pretty_version' => '1.9.1', - 'version' => '1.9.1.0', - 'aliases' => - array ( - ), - 'reference' => 'e4490cabc77465aaee90b20cfc9a770f8c04be6b', - ), - 'http-interop/http-factory-guzzle' => - array ( - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '8f06e92b95405216b237521cc64c804dd44c4a81', - ), - 'illuminate/collections' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '705a4e1ef93cd492c45b9b3e7911cccc990a07f4', - ), - 'illuminate/contracts' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '5e0fd287a1b22a6b346a9f7cd484d8cf0234585d', - ), - 'illuminate/macroable' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => 'aed81891a6e046fdee72edd497f822190f61c162', - ), - 'illuminate/pagination' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '16fe8dc35f9d18c58a3471469af656a02e9ab692', - ), - 'illuminate/support' => - array ( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'aliases' => - array ( - ), - 'reference' => '1c79242468d3bbd9a0f7477df34f9647dde2a09b', - ), - 'league/uri' => - array ( - 'pretty_version' => '6.7.2', - 'version' => '6.7.2.0', - 'aliases' => - array ( - ), - 'reference' => 'd3b50812dd51f3fbf176344cc2981db03d10fe06', - ), - 'league/uri-interfaces' => - array ( - 'pretty_version' => '2.3.0', - 'version' => '2.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '00e7e2943f76d8cb50c7dfdc2f6dee356e15e383', - ), - 'monolog/monolog' => - array ( - 'pretty_version' => '2.9.1', - 'version' => '2.9.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f259e2b15fb95494c83f52d3caad003bbf5ffaa1', - ), - 'nesbot/carbon' => - array ( - 'pretty_version' => '2.69.0', - 'version' => '2.69.0.0', - 'aliases' => - array ( - ), - 'reference' => '4308217830e4ca445583a37d1bf4aff4153fa81c', - ), - 'paragonie/constant_time_encoding' => - array ( - 'pretty_version' => 'v2.6.3', - 'version' => '2.6.3.0', - 'aliases' => - array ( - ), - 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', - ), - 'paragonie/random_compat' => - array ( - 'pretty_version' => 'v2.0.21', - 'version' => '2.0.21.0', - 'aliases' => - array ( - ), - 'reference' => '96c132c7f2f7bc3230723b66e89f8f150b29d5ae', - ), - 'php-http/async-client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - ), - ), - 'php-http/client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - ), - ), - 'php-http/discovery' => - array ( - 'pretty_version' => '1.19.1', - 'version' => '1.19.1.0', - 'aliases' => - array ( - ), - 'reference' => '57f3de01d32085fea20865f9b16fb0e69347c39e', - ), - 'phpmailer/phpmailer' => - array ( - 'pretty_version' => 'v6.8.1', - 'version' => '6.8.1.0', - 'aliases' => - array ( - ), - 'reference' => 'e88da8d679acc3824ff231fdc553565b802ac016', - ), - 'phpseclib/phpseclib' => - array ( - 'pretty_version' => '3.0.21', - 'version' => '3.0.21.0', - 'aliases' => - array ( - ), - 'reference' => '4580645d3fc05c189024eb3b834c6c1e4f0f30a1', - ), - 'psr/clock' => - array ( - 'pretty_version' => '1.0.0', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => 'e41a24703d4560fd0acb709162f73b8adfc3aa0d', - ), - 'psr/clock-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/container' => - array ( - 'pretty_version' => '1.1.2', - 'version' => '1.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', - ), - 'psr/http-client' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31', - ), - 'psr/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '*', - 1 => '1.0', - ), - ), - 'psr/http-factory' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', - ), - 'psr/http-factory-implementation' => - array ( - 'provided' => - array ( - 0 => '^1.0', - 1 => '*', - ), - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.1', - 'version' => '1.1.0.0', - 'aliases' => - array ( - ), - 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - 1 => '*', - ), - ), - 'psr/http-server-handler' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4', - ), - 'psr/http-server-middleware' => - array ( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'aliases' => - array ( - ), - 'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829', - ), - 'psr/log' => - array ( - 'pretty_version' => '1.1.4', - 'version' => '1.1.4.0', - 'aliases' => - array ( - ), - 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', - ), - 'psr/log-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0.0 || 2.0.0 || 3.0.0', - ), - ), - 'psr/simple-cache' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', - ), - 'ralouphie/getallheaders' => - array ( - 'pretty_version' => '3.0.3', - 'version' => '3.0.3.0', - 'aliases' => - array ( - ), - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', - ), - 'ramsey/collection' => - array ( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', - ), - 'ramsey/uuid' => - array ( - 'pretty_version' => '4.2.3', - 'version' => '4.2.3.0', - 'aliases' => - array ( - ), - 'reference' => 'fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df', - ), - 'rhumsaa/uuid' => - array ( - 'replaced' => - array ( - 0 => '4.2.3', - ), - ), - 'spomky-labs/base64url' => - array ( - 'pretty_version' => 'v2.0.4', - 'version' => '2.0.4.0', - 'aliases' => - array ( - ), - 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d', - ), - 'spomky-labs/cbor-php' => - array ( - 'pretty_version' => 'v2.1.0', - 'version' => '2.1.0.0', - 'aliases' => - array ( - ), - 'reference' => '28e2712cfc0b48fae661a48ffc6896d7abe83684', - ), - 'symfony/deprecation-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', - ), - 'symfony/http-client' => - array ( - 'pretty_version' => 'v5.4.26', - 'version' => '5.4.26.0', - 'aliases' => - array ( - ), - 'reference' => '19d48ef7f38e5057ed1789a503cd3eccef039bce', - ), - 'symfony/http-client-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70', - ), - 'symfony/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '2.4', - ), - ), - 'symfony/http-foundation' => - array ( - 'pretty_version' => 'v5.0.7', - 'version' => '5.0.7.0', - 'aliases' => - array ( - ), - 'reference' => '26fb006a2c7b6cdd23d52157b05f8414ffa417b6', - ), - 'symfony/mime' => - array ( - 'pretty_version' => 'v5.4.26', - 'version' => '5.4.26.0', - 'aliases' => - array ( - ), - 'reference' => '2ea06dfeee20000a319d8407cea1d47533d5a9d2', - ), - 'symfony/polyfill-ctype' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', - ), - 'symfony/polyfill-intl-idn' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d', - ), - 'symfony/polyfill-intl-normalizer' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92', - ), - 'symfony/polyfill-mbstring' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '42292d99c55abe617799667f454222c54c60e229', - ), - 'symfony/polyfill-php72' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179', - ), - 'symfony/polyfill-php73' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5', - ), - 'symfony/polyfill-php80' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', - ), - 'symfony/polyfill-php81' => - array ( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'aliases' => - array ( - ), - 'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b', - ), - 'symfony/process' => - array ( - 'pretty_version' => 'v5.4.28', - 'version' => '5.4.28.0', - 'aliases' => - array ( - ), - 'reference' => '45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b', - ), - 'symfony/psr-http-message-bridge' => - array ( - 'pretty_version' => 'v1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '9d3e80d54d9ae747ad573cad796e8e247df7b796', - ), - 'symfony/service-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', - ), - 'symfony/translation' => - array ( - 'pretty_version' => 'v5.4.24', - 'version' => '5.4.24.0', - 'aliases' => - array ( - ), - 'reference' => 'de237e59c5833422342be67402d487fbf50334ff', - ), - 'symfony/translation-contracts' => - array ( - 'pretty_version' => 'v2.5.2', - 'version' => '2.5.2.0', - 'aliases' => - array ( - ), - 'reference' => '136b19dd05cdf0709db6537d058bcab6dd6e2dbe', - ), - 'symfony/translation-implementation' => - array ( - 'provided' => - array ( - 0 => '2.3', - ), - ), - 'thecodingmachine/safe' => - array ( - 'pretty_version' => 'v1.3.3', - 'version' => '1.3.3.0', - 'aliases' => - array ( - ), - 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc', - ), - 'voku/portable-ascii' => - array ( - 'pretty_version' => '1.6.1', - 'version' => '1.6.1.0', - 'aliases' => - array ( - ), - 'reference' => '87337c91b9dfacee02452244ee14ab3c43bc485a', - ), - 'web-auth/cose-lib' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => 'efa6ec2ba4e840bc1316a493973c9916028afeeb', - ), - 'web-auth/metadata-service' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => 'ef40d2b7b68c4964247d13fab52e2fa8dbd65246', - ), - 'web-auth/webauthn-lib' => - array ( - 'pretty_version' => 'v3.3.12', - 'version' => '3.3.12.0', - 'aliases' => - array ( - ), - 'reference' => '5ef9b21c8e9f8a817e524ac93290d08a9f065b33', - ), - 'web-token/jwt-checker' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '5f31d98155951739e2fae7455e8466ccddd08f50', - ), - 'web-token/jwt-core' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '53beb6f6c1eec4fa93c1c3e5d9e5701e71fa1678', - ), - 'web-token/jwt-easy' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '01db23252bb53d4fd36975b55dd58466bab1bb30', - ), - 'web-token/jwt-encryption' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '3b8d67d7c5c013750703e7c27f1001544407bbb2', - ), - 'web-token/jwt-key-mgmt' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '0b116379515700d237b4e5de86879078ccb09d8a', - ), - 'web-token/jwt-signature' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '015b59aaf3b6e8fb9f5bd1338845b7464c7d8103', - ), - 'web-token/jwt-signature-algorithm-rsa' => - array ( - 'pretty_version' => 'v2.2.11', - 'version' => '2.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '513ad90eb5ef1886ff176727a769bda4618141b0', - ), - 'webklex/php-imap' => - array ( - 'pretty_version' => '4.1.2', - 'version' => '4.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '94bf93ae8868ac1e073cfbaef377f0ca1acac2bc', - ), - ), ); diff --git a/lam/lib/3rdParty/composer/composer/platform_check.php b/lam/lib/3rdParty/composer/composer/platform_check.php index 580fa9609..b168ddd5d 100644 --- a/lam/lib/3rdParty/composer/composer/platform_check.php +++ b/lam/lib/3rdParty/composer/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70400)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80002)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.2". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/lam/lib/3rdParty/composer/firebase/php-jwt/CHANGELOG.md b/lam/lib/3rdParty/composer/firebase/php-jwt/CHANGELOG.md index 353766ee0..4279dfd23 100644 --- a/lam/lib/3rdParty/composer/firebase/php-jwt/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/firebase/php-jwt/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04) + + +### Features + +* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2)) + ## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14) diff --git a/lam/lib/3rdParty/composer/firebase/php-jwt/src/BeforeValidException.php b/lam/lib/3rdParty/composer/firebase/php-jwt/src/BeforeValidException.php index c147852b9..595164bf3 100644 --- a/lam/lib/3rdParty/composer/firebase/php-jwt/src/BeforeValidException.php +++ b/lam/lib/3rdParty/composer/firebase/php-jwt/src/BeforeValidException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class BeforeValidException extends \UnexpectedValueException +class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/lam/lib/3rdParty/composer/firebase/php-jwt/src/ExpiredException.php b/lam/lib/3rdParty/composer/firebase/php-jwt/src/ExpiredException.php index 81ba52d43..12fef0944 100644 --- a/lam/lib/3rdParty/composer/firebase/php-jwt/src/ExpiredException.php +++ b/lam/lib/3rdParty/composer/firebase/php-jwt/src/ExpiredException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class ExpiredException extends \UnexpectedValueException +class ExpiredException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWT.php b/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWT.php index 189274525..6efcbb56d 100644 --- a/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWT.php +++ b/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWT.php @@ -153,23 +153,29 @@ public static function decode( // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { - throw new BeforeValidException( + $ex = new BeforeValidException( 'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf) ); + $ex->setPayload($payload); + throw $ex; } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { - throw new BeforeValidException( + $ex = new BeforeValidException( 'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat) ); + $ex->setPayload($payload); + throw $ex; } // Check if this token has expired. if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { - throw new ExpiredException('Expired token'); + $ex = new ExpiredException('Expired token'); + $ex->setPayload($payload); + throw $ex; } return $payload; diff --git a/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php b/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php new file mode 100644 index 000000000..7933ed68b --- /dev/null +++ b/lam/lib/3rdParty/composer/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php @@ -0,0 +1,20 @@ +offsetExists($key); } + if (is_float($key)) { + $key = (string) $key; + } + return array_key_exists($key, $array); } @@ -252,7 +257,7 @@ public static function flatten($array, $depth = INF) * Remove one or many array items from a given array using "dot" notation. * * @param array $array - * @param array|string $keys + * @param array|string|int|float $keys * @return void */ public static function forget(&$array, $keys) @@ -281,7 +286,7 @@ public static function forget(&$array, $keys) while (count($parts) > 1) { $part = array_shift($parts); - if (isset($array[$part]) && is_array($array[$part])) { + if (isset($array[$part]) && static::accessible($array[$part])) { $array = &$array[$part]; } else { continue 2; @@ -314,7 +319,7 @@ public static function get($array, $key, $default = null) return $array[$key]; } - if (strpos($key, '.') === false) { + if (! str_contains($key, '.')) { return $array[$key] ?? value($default); } @@ -423,6 +428,59 @@ public static function isList($array) return ! self::isAssoc($array); } + /** + * Join all items using a string. The final items can use a separate glue string. + * + * @param array $array + * @param string $glue + * @param string $finalGlue + * @return string + */ + public static function join($array, $glue, $finalGlue = '') + { + if ($finalGlue === '') { + return implode($glue, $array); + } + + if (count($array) === 0) { + return ''; + } + + if (count($array) === 1) { + return end($array); + } + + $finalItem = array_pop($array); + + return implode($glue, $array).$finalGlue.$finalItem; + } + + /** + * Key an associative array by a field or using a callback. + * + * @param array $array + * @param callable|array|string $keyBy + * @return array + */ + public static function keyBy($array, $keyBy) + { + return Collection::make($array)->keyBy($keyBy)->all(); + } + + /** + * Prepend the key names of an associative array. + * + * @param array $array + * @param string $prependWith + * @return array + */ + public static function prependKeysWith($array, $prependWith) + { + return Collection::make($array)->mapWithKeys(function ($item, $key) use ($prependWith) { + return [$prependWith.$key => $item]; + })->all(); + } + /** * Get a subset of the items from the given array. * @@ -487,6 +545,26 @@ protected static function explodePluckParameters($value, $key) return [$value, $key]; } + /** + * Run a map over each of the items in the array. + * + * @param array $array + * @param callable $callback + * @return array + */ + public static function map(array $array, callable $callback) + { + $keys = array_keys($array); + + try { + $items = array_map($callback, $array, $keys); + } catch (ArgumentCountError) { + $items = array_map($callback, $array); + } + + return array_combine($keys, $items); + } + /** * Push an item onto the beginning of an array. * @@ -539,7 +617,7 @@ public static function query($array) * * @param array $array * @param int|null $number - * @param bool|false $preserveKeys + * @param bool $preserveKeys * @return mixed * * @throws \InvalidArgumentException @@ -587,7 +665,7 @@ public static function random($array, $number = null, $preserveKeys = false) * If no key is given to the method, the entire array will be replaced. * * @param array $array - * @param string|null $key + * @param string|int|null $key * @param mixed $value * @return array */ @@ -653,6 +731,18 @@ public static function sort($array, $callback = null) return Collection::make($array)->sortBy($callback)->all(); } + /** + * Sort the array in descending order using the given callback or "dot" notation. + * + * @param array $array + * @param callable|array|string|null $callback + * @return array + */ + public static function sortDesc($array, $callback = null) + { + return Collection::make($array)->sortByDesc($callback)->all(); + } + /** * Recursively sort an array by keys and values. * @@ -705,6 +795,29 @@ public static function toCssClasses($array) return implode(' ', $classes); } + /** + * Conditionally compile styles from an array into a style list. + * + * @param array $array + * @return string + */ + public static function toCssStyles($array) + { + $styleList = static::wrap($array); + + $styles = []; + + foreach ($styleList as $class => $constraint) { + if (is_numeric($class)) { + $styles[] = Str::finish($constraint, ';'); + } elseif ($constraint) { + $styles[] = Str::finish($class, ';'); + } + } + + return implode(' ', $styles); + } + /** * Filter the array using the given callback. * @@ -725,9 +838,7 @@ public static function where($array, callable $callback) */ public static function whereNotNull($array) { - return static::where($array, function ($value) { - return ! is_null($value); - }); + return static::where($array, fn ($value) => ! is_null($value)); } /** diff --git a/lam/lib/3rdParty/composer/illuminate/collections/Collection.php b/lam/lib/3rdParty/composer/illuminate/collections/Collection.php index 61a48841c..23bc80d85 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/Collection.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/Collection.php @@ -8,22 +8,33 @@ use Illuminate\Support\Traits\EnumeratesValues; use Illuminate\Support\Traits\Macroable; use stdClass; - +use Traversable; + +/** + * @template TKey of array-key + * @template TValue + * + * @implements \ArrayAccess + * @implements \Illuminate\Support\Enumerable + */ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Illuminate\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The items contained in the collection. * - * @var array + * @var array */ protected $items = []; /** * Create a new collection. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items * @return void */ public function __construct($items = []) @@ -36,7 +47,7 @@ public function __construct($items = []) * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -46,7 +57,7 @@ public static function range($from, $to) /** * Get all of the items in the collection. * - * @return array + * @return array */ public function all() { @@ -56,7 +67,7 @@ public function all() /** * Get a lazy collection for the items in this collection. * - * @return \Illuminate\Support\LazyCollection + * @return \Illuminate\Support\LazyCollection */ public function lazy() { @@ -66,18 +77,16 @@ public function lazy() /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { $callback = $this->valueRetriever($callback); - $items = $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - }); + $items = $this + ->map(fn ($value) => $callback($value)) + ->filter(fn ($value) => ! is_null($value)); if ($count = $items->count()) { return $items->sum() / $count; @@ -87,15 +96,14 @@ public function avg($callback = null) /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { $values = (isset($key) ? $this->pluck($key) : $this) - ->filter(function ($item) { - return ! is_null($item); - })->sort()->values(); + ->filter(fn ($item) => ! is_null($item)) + ->sort()->values(); $count = $values->count(); @@ -117,8 +125,8 @@ public function median($key = null) /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -130,23 +138,20 @@ public function mode($key = null) $counts = new static; - $collection->each(function ($value) use ($counts) { - $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1; - }); + $collection->each(fn ($value) => $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1); $sorted = $counts->sort(); $highestValue = $sorted->last(); - return $sorted->filter(function ($value) use ($highestValue) { - return $value == $highestValue; - })->sort()->keys()->all(); + return $sorted->filter(fn ($value) => $value == $highestValue) + ->sort()->keys()->all(); } /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -156,7 +161,7 @@ public function collapse() /** * Determine if an item exists in the collection. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,6 +181,26 @@ public function contains($key, $operator = null, $value = null) return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + return in_array($key, $this->items, true); + } + /** * Determine if an item is not contained in the collection. * @@ -192,8 +217,11 @@ public function doesntContain($key, $operator = null, $value = null) /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists) { @@ -205,7 +233,7 @@ public function crossJoin(...$lists) /** * Get the items in the collection that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -216,8 +244,8 @@ public function diff($items) /** * Get the items in the collection that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -228,7 +256,7 @@ public function diffUsing($items, callable $callback) /** * Get the items in the collection whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -239,8 +267,8 @@ public function diffAssoc($items) /** * Get the items in the collection whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -251,7 +279,7 @@ public function diffAssocUsing($items, callable $callback) /** * Get the items in the collection whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -262,8 +290,8 @@ public function diffKeys($items) /** * Get the items in the collection whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -274,7 +302,7 @@ public function diffKeysUsing($items, callable $callback) /** * Retrieve duplicate items from the collection. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -302,7 +330,7 @@ public function duplicates($callback = null, $strict = false) /** * Retrieve duplicate items from the collection using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -314,25 +342,21 @@ public function duplicatesStrict($callback = null) * Get the comparison function to detect duplicates. * * @param bool $strict - * @return \Closure + * @return callable(TValue, TValue): bool */ protected function duplicateComparator($strict) { if ($strict) { - return function ($a, $b) { - return $a === $b; - }; + return fn ($a, $b) => $a === $b; } - return function ($a, $b) { - return $a == $b; - }; + return fn ($a, $b) => $a == $b; } /** * Get all items except for those with the specified keys. * - * @param \Illuminate\Support\Collection|mixed $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -349,7 +373,7 @@ public function except($keys) /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ public function filter(callable $callback = null) @@ -364,9 +388,11 @@ public function filter(callable $callback = null) /** * Get the first item from the collection passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -377,7 +403,7 @@ public function first(callable $callback = null, $default = null) * Get a flattened array of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -387,7 +413,7 @@ public function flatten($depth = INF) /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -397,7 +423,7 @@ public function flip() /** * Remove an item from the collection by key. * - * @param string|int|array $keys + * @param TKey|array $keys * @return $this */ public function forget($keys) @@ -412,9 +438,11 @@ public function forget($keys) /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -446,9 +474,9 @@ public function getOrPut($key, $value) /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -470,7 +498,11 @@ public function groupBy($groupBy, $preserveKeys = false) } foreach ($groupKeys as $groupKey) { - $groupKey = is_bool($groupKey) ? (int) $groupKey : $groupKey; + $groupKey = match (true) { + is_bool($groupKey) => (int) $groupKey, + $groupKey instanceof \Stringable => (string) $groupKey, + default => $groupKey, + }; if (! array_key_exists($groupKey, $results)) { $results[$groupKey] = new static; @@ -492,8 +524,8 @@ public function groupBy($groupBy, $preserveKeys = false) /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -517,7 +549,7 @@ public function keyBy($keyBy) /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key) @@ -559,12 +591,16 @@ public function hasAny($key) /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ public function implode($value, $glue = null) { + if ($this->useAsCallable($value)) { + return implode($glue ?? '', $this->map($value)->all()); + } + $first = $this->first(); if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) { @@ -577,7 +613,7 @@ public function implode($value, $glue = null) /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -585,10 +621,45 @@ public function intersect($items) return new static(array_intersect($this->items, $this->getArrayableItems($items))); } + /** + * Intersect the collection with the given items, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectUsing($items, callable $callback) + { + return new static(array_uintersect($this->items, $this->getArrayableItems($items), $callback)); + } + + /** + * Intersect the collection with the given items with additional index check. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static + */ + public function intersectAssoc($items) + { + return new static(array_intersect_assoc($this->items, $this->getArrayableItems($items))); + } + + /** + * Intersect the collection with the given items with additional index check, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectAssocUsing($items, callable $callback) + { + return new static(array_intersect_uassoc($this->items, $this->getArrayableItems($items), $callback)); + } + /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -651,7 +722,7 @@ public function join($glue, $finalGlue = '') /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -661,9 +732,11 @@ public function keys() /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -673,9 +746,9 @@ public function last(callable $callback = null, $default = null) /** * Get the values of a given key. * - * @param string|array|int|null $value + * @param string|int|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -685,16 +758,14 @@ public function pluck($value, $key = null) /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { - $keys = array_keys($this->items); - - $items = array_map($callback, $this->items, $keys); - - return new static(array_combine($keys, $items)); + return new static(Arr::map($this->items, $callback)); } /** @@ -702,8 +773,11 @@ public function map(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -731,8 +805,11 @@ public function mapToDictionary(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { @@ -752,7 +829,7 @@ public function mapWithKeys(callable $callback) /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -763,8 +840,10 @@ public function merge($items) /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -774,8 +853,10 @@ public function mergeRecursive($items) /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values) { @@ -785,7 +866,7 @@ public function combine($values) /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -820,7 +901,7 @@ public function nth($step, $offset = 0) /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string|null $keys * @return static */ public function only($keys) @@ -842,7 +923,7 @@ public function only($keys) * Get and remove the last N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function pop($count = 1) { @@ -868,8 +949,8 @@ public function pop($count = 1) /** * Push an item onto the beginning of the collection. * - * @param mixed $value - * @param mixed $key + * @param TValue $value + * @param TKey $key * @return $this */ public function prepend($value, $key = null) @@ -882,7 +963,7 @@ public function prepend($value, $key = null) /** * Push one or more items onto the end of the collection. * - * @param mixed $values + * @param TValue ...$values * @return $this */ public function push(...$values) @@ -897,7 +978,7 @@ public function push(...$values) /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source) @@ -914,9 +995,11 @@ public function concat($source) /** * Get and remove an item from the collection. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TPullDefault + * + * @param TKey $key + * @param TPullDefault|(\Closure(): TPullDefault) $default + * @return TValue|TPullDefault */ public function pull($key, $default = null) { @@ -926,8 +1009,8 @@ public function pull($key, $default = null) /** * Put an item in the collection by key. * - * @param mixed $key - * @param mixed $value + * @param TKey $key + * @param TValue $value * @return $this */ public function put($key, $value) @@ -940,8 +1023,8 @@ public function put($key, $value) /** * Get one or a specified number of items randomly from the collection. * - * @param int|null $number - * @return static|mixed + * @param (callable(self): int)|int|null $number + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -951,13 +1034,17 @@ public function random($number = null) return Arr::random($this->items); } + if (is_callable($number)) { + return new static(Arr::random($this->items, $number($this))); + } + return new static(Arr::random($this->items, $number)); } /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -968,7 +1055,7 @@ public function replace($items) /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -989,9 +1076,9 @@ public function reverse() /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false) { @@ -1012,7 +1099,7 @@ public function search($value, $strict = false) * Get and remove the first N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function shift($count = 1) { @@ -1051,7 +1138,7 @@ public function shuffle($seed = null) * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { @@ -1076,7 +1163,7 @@ public function skip($count) /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1087,7 +1174,7 @@ public function skipUntil($value) /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1111,7 +1198,7 @@ public function slice($offset, $length = null) * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1148,7 +1235,7 @@ public function split($numberOfGroups) * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1158,10 +1245,10 @@ public function splitIn($numberOfGroups) /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException @@ -1172,14 +1259,16 @@ public function sole($key = null, $operator = null, $value = null) ? $this->operatorForWhere(...func_get_args()) : $key; - $items = $this->when($filter)->filter($filter); + $items = $this->unless($filter == null)->filter($filter); + + $count = $items->count(); - if ($items->isEmpty()) { + if ($count === 0) { throw new ItemNotFoundException; } - if ($items->count() > 1) { - throw new MultipleItemsFoundException; + if ($count > 1) { + throw new MultipleItemsFoundException($count); } return $items->first(); @@ -1188,10 +1277,10 @@ public function sole($key = null, $operator = null, $value = null) /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException */ @@ -1216,7 +1305,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1236,8 +1325,8 @@ public function chunk($size) /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1249,7 +1338,7 @@ public function chunkWhile(callable $callback) /** * Sort through each item with a callback. * - * @param callable|int|null $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1281,7 +1370,7 @@ public function sortDesc($options = SORT_REGULAR) /** * Sort the collection using the given callback. * - * @param callable|array|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1319,14 +1408,14 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) /** * Sort the collection using multiple comparisons. * - * @param array $comparisons + * @param array $comparisons * @return static */ protected function sortByMany(array $comparisons = []) { $items = $this->items; - usort($items, function ($a, $b) use ($comparisons) { + uasort($items, function ($a, $b) use ($comparisons) { foreach ($comparisons as $comparison) { $comparison = Arr::wrap($comparison); @@ -1335,8 +1424,6 @@ protected function sortByMany(array $comparisons = []) $ascending = Arr::get($comparison, 1, true) === true || Arr::get($comparison, 1, true) === 'asc'; - $result = 0; - if (! is_string($prop) && is_callable($prop)) { $result = $prop($a, $b); } else { @@ -1363,7 +1450,7 @@ protected function sortByMany(array $comparisons = []) /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -1402,7 +1489,7 @@ public function sortKeysDesc($options = SORT_REGULAR) /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1419,7 +1506,7 @@ public function sortKeysUsing(callable $callback) * * @param int $offset * @param int|null $length - * @param mixed $replacement + * @param array $replacement * @return static */ public function splice($offset, $length = null, $replacement = []) @@ -1449,7 +1536,7 @@ public function take($limit) /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) @@ -1460,7 +1547,7 @@ public function takeUntil($value) /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) @@ -1471,7 +1558,7 @@ public function takeWhile($value) /** * Transform each item in the collection using a callback. * - * @param callable $callback + * @param callable(TValue, TKey): TValue $callback * @return $this */ public function transform(callable $callback) @@ -1494,7 +1581,7 @@ public function undot() /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1520,7 +1607,7 @@ public function unique($key = null, $strict = false) /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1533,18 +1620,16 @@ public function values() * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items) { - $arrayableItems = array_map(function ($items) { - return $this->getArrayableItems($items); - }, func_get_args()); + $arrayableItems = array_map(fn ($items) => $this->getArrayableItems($items), func_get_args()); - $params = array_merge([function () { - return new static(func_get_args()); - }, $this->items], $arrayableItems); + $params = array_merge([fn () => new static(func_get_args()), $this->items], $arrayableItems); return new static(array_map(...$params)); } @@ -1552,9 +1637,11 @@ public function zip($items) /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1564,10 +1651,9 @@ public function pad($size, $value) /** * Get an iterator for the items. * - * @return \ArrayIterator + * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->items); } @@ -1577,8 +1663,7 @@ public function getIterator() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->items); } @@ -1586,8 +1671,8 @@ public function count() /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -1597,7 +1682,7 @@ public function countBy($countBy = null) /** * Add an item to the collection. * - * @param mixed $item + * @param TValue $item * @return $this */ public function add($item) @@ -1610,7 +1695,7 @@ public function add($item) /** * Get a base Support collection instance from this collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function toBase() { @@ -1620,11 +1705,10 @@ public function toBase() /** * Determine if an item exists at an offset. * - * @param mixed $key + * @param TKey $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return isset($this->items[$key]); } @@ -1632,11 +1716,10 @@ public function offsetExists($key) /** * Get an item at a given offset. * - * @param mixed $key - * @return mixed + * @param TKey $key + * @return TValue */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items[$key]; } @@ -1644,12 +1727,11 @@ public function offsetGet($key) /** * Set the item at a given offset. * - * @param mixed $key - * @param mixed $value + * @param TKey|null $key + * @param TValue $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { if (is_null($key)) { $this->items[] = $value; @@ -1661,11 +1743,10 @@ public function offsetSet($key, $value) /** * Unset the item at a given offset. * - * @param mixed $key + * @param TKey $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { unset($this->items[$key]); } diff --git a/lam/lib/3rdParty/composer/illuminate/collections/Enumerable.php b/lam/lib/3rdParty/composer/illuminate/collections/Enumerable.php index 261a0c856..070b5650c 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/Enumerable.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/Enumerable.php @@ -2,19 +2,31 @@ namespace Illuminate\Support; +use CachingIterator; use Countable; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Jsonable; use IteratorAggregate; use JsonSerializable; - +use Traversable; + +/** + * @template TKey of array-key + * @template TValue + * + * @extends \Illuminate\Contracts\Support\Arrayable + * @extends \IteratorAggregate + */ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable { /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []); @@ -39,16 +51,21 @@ public static function range($from, $to); /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value); /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value); @@ -69,38 +86,38 @@ public function all(); /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null); /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null); /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null); /** * Collapse the items into a single enumerable. * - * @return static + * @return static */ public function collapse(); /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -110,8 +127,8 @@ public function some($key, $operator = null, $value = null); /** * Determine if an item exists, using strict comparison. * - * @param mixed $key - * @param mixed $value + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value * @return bool */ public function containsStrict($key, $value = null); @@ -119,26 +136,39 @@ public function containsStrict($key, $value = null); /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null); /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool */ public function contains($key, $operator = null, $value = null); + /** + * Determine if an item is not contained in the collection. + * + * @param mixed $key + * @param mixed $operator + * @param mixed $value + * @return bool + */ + public function doesntContain($key, $operator = null, $value = null); + /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists); @@ -146,7 +176,7 @@ public function crossJoin(...$lists); * Dump the collection and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args); @@ -160,7 +190,7 @@ public function dump(); /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items); @@ -168,8 +198,8 @@ public function diff($items); /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback); @@ -177,7 +207,7 @@ public function diffUsing($items, callable $callback); /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items); @@ -185,8 +215,8 @@ public function diffAssoc($items); /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback); @@ -194,7 +224,7 @@ public function diffAssocUsing($items, callable $callback); /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items); @@ -202,8 +232,8 @@ public function diffKeys($items); /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback); @@ -211,7 +241,7 @@ public function diffKeysUsing($items, callable $callback); /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -220,7 +250,7 @@ public function duplicates($callback = null, $strict = false); /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null); @@ -228,7 +258,7 @@ public function duplicatesStrict($callback = null); /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback); @@ -244,7 +274,7 @@ public function eachSpread(callable $callback); /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -254,7 +284,7 @@ public function every($key, $operator = null, $value = null); /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys); @@ -262,64 +292,76 @@ public function except($keys); /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue): bool)|null $callback * @return static */ public function filter(callable $callback = null); /** - * Apply the callback if the value is truthy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TWhenReturnType as null * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TWhenReturnType)|null $callback + * @param (callable($this): TWhenReturnType)|null $default + * @return $this|TWhenReturnType */ - public function when($value, callable $callback, callable $default = null); + public function when($value, callable $callback = null, callable $default = null); /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null); /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null); /** - * Apply the callback if the value is falsy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TUnlessReturnType * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TUnlessReturnType) $callback + * @param (callable($this): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType */ public function unless($value, callable $callback, callable $default = null); /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null); /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null); @@ -362,7 +404,7 @@ public function whereStrict($key, $value); * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -372,7 +414,7 @@ public function whereIn($key, $values, $strict = false); * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values); @@ -381,7 +423,7 @@ public function whereInStrict($key, $values); * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values); @@ -390,7 +432,7 @@ public function whereBetween($key, $values); * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values); @@ -399,7 +441,7 @@ public function whereNotBetween($key, $values); * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -409,7 +451,7 @@ public function whereNotIn($key, $values, $strict = false); * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values); @@ -417,17 +459,21 @@ public function whereNotInStrict($key, $values); /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type); /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue,TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null); @@ -437,7 +483,7 @@ public function first(callable $callback = null, $default = null); * @param string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null); @@ -452,44 +498,54 @@ public function flatten($depth = INF); /** * Flip the values with their keys. * - * @return static + * @return static */ public function flip(); /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null); /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false); /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy); /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key); + /** + * Determine if any of the keys exist in the collection. + * + * @param mixed $key + * @return bool + */ + public function hasAny($key); + /** * Concatenate values of a given key as a string. * @@ -502,7 +558,7 @@ public function implode($value, $glue = null); /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items); @@ -510,7 +566,7 @@ public function intersect($items); /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items); @@ -529,6 +585,13 @@ public function isEmpty(); */ public function isNotEmpty(); + /** + * Determine if the collection contains a single item. + * + * @return bool + */ + public function containsOneItem(); + /** * Join all items from the collection using a string. The final items can use a separate glue string. * @@ -541,24 +604,28 @@ public function join($glue, $finalGlue = ''); /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys(); /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null); /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback); @@ -575,8 +642,11 @@ public function mapSpread(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback); @@ -585,8 +655,11 @@ public function mapToDictionary(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback); @@ -595,31 +668,39 @@ public function mapToGroups(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback); /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback); /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class); /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items); @@ -627,23 +708,27 @@ public function merge($items); /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items); /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values); /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items); @@ -651,7 +736,7 @@ public function union($items); /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null); @@ -659,7 +744,7 @@ public function min($callback = null); /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null); @@ -676,7 +761,7 @@ public function nth($step, $offset = 0); /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys); @@ -693,17 +778,17 @@ public function forPage($page, $perPage); /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value - * @return static + * @return static, static> */ public function partition($key, $operator = null, $value = null); /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source); @@ -712,7 +797,7 @@ public function concat($source); * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -721,16 +806,30 @@ public function random($number = null); /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null); + /** + * Reduce the collection to multiple aggregate values. + * + * @param callable $callback + * @param mixed ...$initial + * @return array + * + * @throws \UnexpectedValueException + */ + public function reduceSpread(callable $callback, ...$initial); + /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items); @@ -738,7 +837,7 @@ public function replace($items); /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items); @@ -753,9 +852,9 @@ public function reverse(); /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false); @@ -767,6 +866,15 @@ public function search($value, $strict = false); */ public function shuffle($seed = null); + /** + * Create chunks representing a "sliding window" view of the items in the collection. + * + * @param int $size + * @param int $step + * @return static + */ + public function sliding($size = 2, $step = 1); + /** * Skip the first {$count} items. * @@ -778,7 +886,7 @@ public function skip($count); /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value); @@ -786,7 +894,7 @@ public function skipUntil($value); /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value); @@ -804,30 +912,63 @@ public function slice($offset, $length = null); * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups); + /** + * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Illuminate\Support\ItemNotFoundException + * @throws \Illuminate\Support\MultipleItemsFoundException + */ + public function sole($key = null, $operator = null, $value = null); + + /** + * Get the first item in the collection but throw an exception if no matching items exist. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Illuminate\Support\ItemNotFoundException + */ + public function firstOrFail($key = null, $operator = null, $value = null); + /** * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size); /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback); + /** + * Split a collection into a certain number of groups, and fill the first groups completely. + * + * @param int $numberOfGroups + * @return static + */ + public function splitIn($numberOfGroups); + /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null); @@ -843,7 +984,7 @@ public function sortDesc($options = SORT_REGULAR); /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -853,7 +994,7 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false); /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -876,10 +1017,18 @@ public function sortKeys($options = SORT_REGULAR, $descending = false); */ public function sortKeysDesc($options = SORT_REGULAR); + /** + * Sort the collection keys using a callback. + * + * @param callable(TKey, TKey): int $callback + * @return static + */ + public function sortKeysUsing(callable $callback); + /** * Get the sum of the given values. * - * @param callable|string|null $callback + * @param (callable(TValue): mixed)|string|null $callback * @return mixed */ public function sum($callback = null); @@ -895,7 +1044,7 @@ public function take($limit); /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value); @@ -903,7 +1052,7 @@ public function takeUntil($value); /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value); @@ -911,7 +1060,7 @@ public function takeWhile($value); /** * Pass the collection to the given callback and then return it. * - * @param callable $callback + * @param callable(TValue): mixed $callback * @return $this */ public function tap(callable $callback); @@ -919,32 +1068,57 @@ public function tap(callable $callback); /** * Pass the enumerable to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback); + /** + * Pass the collection into a new class. + * + * @param class-string $class + * @return mixed + */ + public function pipeInto($class); + + /** + * Pass the collection through a series of callable pipes and return the result. + * + * @param array $pipes + * @return mixed + */ + public function pipeThrough($pipes); + /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null); /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true); + /** + * Convert a flatten "dot" notation array into an expanded array. + * + * @return static + */ + public function undot(); + /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -953,7 +1127,7 @@ public function unique($key = null, $strict = false); /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null); @@ -961,26 +1135,42 @@ public function uniqueStrict($key = null); /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values(); /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value); /** - * Count the number of items in the collection using a given truth test. + * Get the values iterator. * - * @param callable|null $callback - * @return static + * @return \Traversable */ - public function countBy($callback = null); + public function getIterator(): Traversable; + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count(): int; + + /** + * Count the number of items in the collection by a field or using a callback. + * + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static + */ + public function countBy($countBy = null); /** * Zip the collection together with one or more arrays. @@ -988,18 +1178,50 @@ public function countBy($callback = null); * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items); /** * Collect the values into a collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect(); + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function toArray(); + + /** + * Convert the object into something JSON serializable. + * + * @return mixed + */ + public function jsonSerialize(): mixed; + + /** + * Get the collection of items as JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0); + + /** + * Get a CachingIterator instance. + * + * @param int $flags + * @return \CachingIterator + */ + public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING); + /** * Convert the collection to its string representation. * @@ -1007,6 +1229,14 @@ public function collect(); */ public function __toString(); + /** + * Indicate that the model's string representation should be escaped when __toString is invoked. + * + * @param bool $escape + * @return $this + */ + public function escapeWhenCastingToString($escape = true); + /** * Add a method to the list of proxied methods. * diff --git a/lam/lib/3rdParty/composer/illuminate/collections/HigherOrderWhenProxy.php b/lam/lib/3rdParty/composer/illuminate/collections/HigherOrderWhenProxy.php deleted file mode 100644 index 6653c03a6..000000000 --- a/lam/lib/3rdParty/composer/illuminate/collections/HigherOrderWhenProxy.php +++ /dev/null @@ -1,63 +0,0 @@ -condition = $condition; - $this->collection = $collection; - } - - /** - * Proxy accessing an attribute onto the collection. - * - * @param string $key - * @return mixed - */ - public function __get($key) - { - return $this->condition - ? $this->collection->{$key} - : $this->collection; - } - - /** - * Proxy a method call onto the collection. - * - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call($method, $parameters) - { - return $this->condition - ? $this->collection->{$method}(...$parameters) - : $this->collection; - } -} diff --git a/lam/lib/3rdParty/composer/illuminate/collections/LazyCollection.php b/lam/lib/3rdParty/composer/illuminate/collections/LazyCollection.php index e1cdcd99d..8119b3af2 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/LazyCollection.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/LazyCollection.php @@ -5,27 +5,39 @@ use ArrayIterator; use Closure; use DateTimeInterface; +use Generator; use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString; use Illuminate\Support\Traits\EnumeratesValues; use Illuminate\Support\Traits\Macroable; +use InvalidArgumentException; use IteratorAggregate; use stdClass; - +use Traversable; + +/** + * @template TKey of array-key + * @template TValue + * + * @implements \Illuminate\Support\Enumerable + */ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Illuminate\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The source from which to generate items. * - * @var callable|static + * @var (Closure(): \Generator)|static|array */ public $source; /** * Create a new lazy collection instance. * - * @param mixed $source + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source * @return void */ public function __construct($source = null) @@ -34,17 +46,35 @@ public function __construct($source = null) $this->source = $source; } elseif (is_null($source)) { $this->source = static::empty(); + } elseif ($source instanceof Generator) { + throw new InvalidArgumentException( + 'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.' + ); } else { $this->source = $this->getArrayableItems($source); } } + /** + * Create a new collection instance if the value isn't one already. + * + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items + * @return static + */ + public static function make($items = []) + { + return new static($items); + } + /** * Create a collection with the given range. * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -64,7 +94,7 @@ public static function range($from, $to) /** * Get all items in the enumerable. * - * @return array + * @return array */ public function all() { @@ -126,8 +156,8 @@ public function remember() /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { @@ -137,8 +167,8 @@ public function avg($callback = null) /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { @@ -148,8 +178,8 @@ public function median($key = null) /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -159,7 +189,7 @@ public function mode($key = null) /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -177,7 +207,7 @@ public function collapse() /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -187,6 +217,7 @@ public function contains($key, $operator = null, $value = null) if (func_num_args() === 1 && $this->useAsCallable($key)) { $placeholder = new stdClass; + /** @var callable $key */ return $this->first($key, $placeholder) !== $placeholder; } @@ -205,6 +236,32 @@ public function contains($key, $operator = null, $value = null) return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + foreach ($this as $item) { + if ($item === $key) { + return true; + } + } + + return false; + } + /** * Determine if an item is not contained in the enumerable. * @@ -221,8 +278,11 @@ public function doesntContain($key, $operator = null, $value = null) /** * Cross join the given iterables, returning all possible permutations. * - * @param array ...$arrays - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$arrays + * @return static> */ public function crossJoin(...$arrays) { @@ -232,8 +292,8 @@ public function crossJoin(...$arrays) /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -261,7 +321,7 @@ public function countBy($countBy = null) /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -272,8 +332,8 @@ public function diff($items) /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -284,7 +344,7 @@ public function diffUsing($items, callable $callback) /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -295,8 +355,8 @@ public function diffAssoc($items) /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -307,7 +367,7 @@ public function diffAssocUsing($items, callable $callback) /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -318,8 +378,8 @@ public function diffKeys($items) /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -330,7 +390,7 @@ public function diffKeysUsing($items, callable $callback) /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -342,7 +402,7 @@ public function duplicates($callback = null, $strict = false) /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -353,7 +413,7 @@ public function duplicatesStrict($callback = null) /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -364,15 +424,13 @@ public function except($keys) /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ public function filter(callable $callback = null) { if (is_null($callback)) { - $callback = function ($value) { - return (bool) $value; - }; + $callback = fn ($value) => (bool) $value; } return new static(function () use ($callback) { @@ -387,9 +445,11 @@ public function filter(callable $callback = null) /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -416,7 +476,7 @@ public function first(callable $callback = null, $default = null) * Get a flattened list of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -438,7 +498,7 @@ public function flatten($depth = INF) /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -452,9 +512,11 @@ public function flip() /** * Get an item by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey|null $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -474,9 +536,9 @@ public function get($key, $default = null) /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -486,8 +548,8 @@ public function groupBy($groupBy, $preserveKeys = false) /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -548,7 +610,7 @@ public function hasAny($key) /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ @@ -560,7 +622,7 @@ public function implode($value, $glue = null) /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -568,10 +630,45 @@ public function intersect($items) return $this->passthru('intersect', func_get_args()); } + /** + * Intersect the collection with the given items, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectUsing() + { + return $this->passthru('intersectUsing', func_get_args()); + } + + /** + * Intersect the collection with the given items with additional index check. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static + */ + public function intersectAssoc($items) + { + return $this->passthru('intersectAssoc', func_get_args()); + } + + /** + * Intersect the collection with the given items with additional index check, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectAssocUsing($items, callable $callback) + { + return $this->passthru('intersectAssocUsing', func_get_args()); + } + /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -614,7 +711,7 @@ public function join($glue, $finalGlue = '') /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -628,9 +725,11 @@ public function keys() /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -648,9 +747,9 @@ public function last(callable $callback = null, $default = null) /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -678,8 +777,10 @@ public function pluck($value, $key = null) /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { @@ -695,8 +796,11 @@ public function map(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -708,8 +812,11 @@ public function mapToDictionary(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { @@ -723,7 +830,7 @@ public function mapWithKeys(callable $callback) /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -734,8 +841,10 @@ public function merge($items) /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -745,8 +854,10 @@ public function mergeRecursive($items) /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $values + * @return static */ public function combine($values) { @@ -776,7 +887,7 @@ public function combine($values) /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -809,7 +920,7 @@ public function nth($step, $offset = 0) /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys) @@ -844,7 +955,7 @@ public function only($keys) /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source) @@ -859,7 +970,7 @@ public function concat($source) * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -873,7 +984,7 @@ public function random($number = null) /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -900,7 +1011,7 @@ public function replace($items) /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -921,12 +1032,13 @@ public function reverse() /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false) { + /** @var (callable(TValue,TKey): bool) $predicate */ $predicate = $this->useAsCallable($value) ? $value : function ($item) use ($value, $strict) { @@ -958,7 +1070,7 @@ public function shuffle($seed = null) * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { @@ -971,7 +1083,7 @@ public function sliding($size = 2, $step = 1) $chunk[$iterator->key()] = $iterator->current(); if (count($chunk) == $size) { - yield tap(new static($chunk), function () use (&$chunk, $step) { + yield (new static($chunk))->tap(function () use (&$chunk, $step) { $chunk = array_slice($chunk, $step, null, true); }); @@ -1018,7 +1130,7 @@ public function skip($count) /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1031,7 +1143,7 @@ public function skipUntil($value) /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1075,7 +1187,7 @@ public function slice($offset, $length = null) * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1085,10 +1197,10 @@ public function split($numberOfGroups) /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException @@ -1100,7 +1212,7 @@ public function sole($key = null, $operator = null, $value = null) : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(2) ->collect() @@ -1110,10 +1222,10 @@ public function sole($key = null, $operator = null, $value = null) /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException */ @@ -1124,7 +1236,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(1) ->collect() @@ -1135,7 +1247,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1174,7 +1286,7 @@ public function chunk($size) * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1184,8 +1296,8 @@ public function splitIn($numberOfGroups) /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, Collection): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1221,7 +1333,7 @@ public function chunkWhile(callable $callback) /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1243,7 +1355,7 @@ public function sortDesc($options = SORT_REGULAR) /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1256,7 +1368,7 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -1291,7 +1403,7 @@ public function sortKeysDesc($options = SORT_REGULAR) /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1331,11 +1443,12 @@ public function take($limit) /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) { + /** @var callable(TValue, TKey): bool $callback */ $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return new static(function () use ($callback) { @@ -1359,30 +1472,39 @@ public function takeUntilTimeout(DateTimeInterface $timeout) { $timeout = $timeout->getTimestamp(); - return $this->takeWhile(function () use ($timeout) { - return $this->now() < $timeout; + return new static(function () use ($timeout) { + if ($this->now() >= $timeout) { + return; + } + + foreach ($this as $key => $value) { + yield $key => $value; + + if ($this->now() >= $timeout) { + break; + } + } }); } /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) { + /** @var callable(TValue, TKey): bool $callback */ $callback = $this->useAsCallable($value) ? $value : $this->equality($value); - return $this->takeUntil(function ($item, $key) use ($callback) { - return ! $callback($item, $key); - }); + return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key)); } /** * Pass each item in the collection to the given callback, lazily. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return static */ public function tapEach(callable $callback) @@ -1409,7 +1531,7 @@ public function undot() /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1433,7 +1555,7 @@ public function unique($key = null, $strict = false) /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1450,8 +1572,10 @@ public function values() * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items) { @@ -1473,9 +1597,11 @@ public function zip($items) /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1501,10 +1627,9 @@ public function pad($size, $value) /** * Get the values iterator. * - * @return \Traversable + * @return \Traversable */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->makeIterator($this->source); } @@ -1514,8 +1639,7 @@ public function getIterator() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { if (is_array($this->source)) { return count($this->source); @@ -1527,8 +1651,11 @@ public function count() /** * Make an iterator from the given source. * - * @param mixed $source - * @return \Traversable + * @template TIteratorKey of array-key + * @template TIteratorValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $source + * @return \Traversable */ protected function makeIterator($source) { @@ -1540,15 +1667,23 @@ protected function makeIterator($source) return new ArrayIterator($source); } - return $source(); + if (is_callable($source)) { + $maybeTraversable = $source(); + + return $maybeTraversable instanceof Traversable + ? $maybeTraversable + : new ArrayIterator(Arr::wrap($maybeTraversable)); + } + + return new ArrayIterator((array) $source); } /** * Explode the "value" and "key" arguments passed to "pluck". * - * @param string|array $value - * @param string|array|null $key - * @return array + * @param string|string[] $value + * @param string|string[]|null $key + * @return array{string[],string[]|null} */ protected function explodePluckParameters($value, $key) { @@ -1563,7 +1698,7 @@ protected function explodePluckParameters($value, $key) * Pass this lazy collection through a method on the collection class. * * @param string $method - * @param array $params + * @param array $params * @return static */ protected function passthru($method, array $params) diff --git a/lam/lib/3rdParty/composer/illuminate/collections/MultipleItemsFoundException.php b/lam/lib/3rdParty/composer/illuminate/collections/MultipleItemsFoundException.php index 944b2dc64..d90d835b4 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/MultipleItemsFoundException.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/MultipleItemsFoundException.php @@ -6,4 +6,35 @@ class MultipleItemsFoundException extends RuntimeException { + /** + * The number of items found. + * + * @var int + */ + public $count; + + /** + * Create a new exception instance. + * + * @param int $count + * @param int $code + * @param \Throwable|null $previous + * @return void + */ + public function __construct($count, $code = 0, $previous = null) + { + $this->count = $count; + + parent::__construct("$count items were found.", $code, $previous); + } + + /** + * Get the number of items found. + * + * @return int + */ + public function getCount() + { + return $this->count; + } } diff --git a/lam/lib/3rdParty/composer/illuminate/collections/Traits/EnumeratesValues.php b/lam/lib/3rdParty/composer/illuminate/collections/Traits/EnumeratesValues.php index 269d1a666..2ffbe8d70 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/Traits/EnumeratesValues.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/Traits/EnumeratesValues.php @@ -11,7 +11,6 @@ use Illuminate\Support\Collection; use Illuminate\Support\Enumerable; use Illuminate\Support\HigherOrderCollectionProxy; -use Illuminate\Support\HigherOrderWhenProxy; use JsonSerializable; use Symfony\Component\VarDumper\VarDumper; use Traversable; @@ -19,6 +18,9 @@ use UnitEnum; /** + * @template TKey of array-key + * @template TValue + * * @property-read HigherOrderCollectionProxy $average * @property-read HigherOrderCollectionProxy $avg * @property-read HigherOrderCollectionProxy $contains @@ -35,19 +37,23 @@ * @property-read HigherOrderCollectionProxy $min * @property-read HigherOrderCollectionProxy $partition * @property-read HigherOrderCollectionProxy $reject + * @property-read HigherOrderCollectionProxy $skipUntil + * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $some * @property-read HigherOrderCollectionProxy $sortBy * @property-read HigherOrderCollectionProxy $sortByDesc - * @property-read HigherOrderCollectionProxy $skipUntil - * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $takeUntil * @property-read HigherOrderCollectionProxy $takeWhile * @property-read HigherOrderCollectionProxy $unique + * @property-read HigherOrderCollectionProxy $unless * @property-read HigherOrderCollectionProxy $until + * @property-read HigherOrderCollectionProxy $when */ trait EnumeratesValues { + use Conditionable; + /** * Indicates that the object's string representation should be escaped when __toString is invoked. * @@ -58,7 +64,7 @@ trait EnumeratesValues /** * The methods that can be proxied. * - * @var string[] + * @var array */ protected static $proxies = [ 'average', @@ -86,14 +92,19 @@ trait EnumeratesValues 'takeUntil', 'takeWhile', 'unique', + 'unless', 'until', + 'when', ]; /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []) { @@ -103,8 +114,10 @@ public static function make($items = []) /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value) { @@ -116,8 +129,11 @@ public static function wrap($value) /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value) { @@ -137,9 +153,11 @@ public static function empty() /** * Create a new collection by invoking the callback a given amount of times. * + * @template TTimesValue + * * @param int $number - * @param callable|null $callback - * @return static + * @param (callable(int): TTimesValue)|null $callback + * @return static */ public static function times($number, callable $callback = null) { @@ -148,15 +166,15 @@ public static function times($number, callable $callback = null) } return static::range(1, $number) - ->when($callback) + ->unless($callback == null) ->map($callback); } /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null) { @@ -166,7 +184,7 @@ public function average($callback = null) /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,39 +194,11 @@ public function some($key, $operator = null, $value = null) return $this->contains(...func_get_args()); } - /** - * Determine if an item exists, using strict comparison. - * - * @param mixed $key - * @param mixed $value - * @return bool - */ - public function containsStrict($key, $value = null) - { - if (func_num_args() === 2) { - return $this->contains(function ($item) use ($key, $value) { - return data_get($item, $key) === $value; - }); - } - - if ($this->useAsCallable($key)) { - return ! is_null($this->first($key)); - } - - foreach ($this as $item) { - if ($item === $key) { - return true; - } - } - - return false; - } - /** * Dump the items and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args) { @@ -236,7 +226,7 @@ public function dump() /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback) @@ -253,7 +243,7 @@ public function each(callable $callback) /** * Execute a callback over each nested chunk of items. * - * @param callable $callback + * @param callable(...mixed): mixed $callback * @return static */ public function eachSpread(callable $callback) @@ -268,7 +258,7 @@ public function eachSpread(callable $callback) /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -293,16 +283,32 @@ public function every($key, $operator = null, $value = null) /** * Get the first item by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null) { return $this->first($this->operatorForWhere(...func_get_args())); } + /** + * Get a single key's value from the first matching item in the collection. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function value($key, $default = null) + { + if ($value = $this->firstWhere($key)) { + return data_get($value, $key, $default); + } + + return value($default); + } + /** * Determine if the collection is not empty. * @@ -316,8 +322,10 @@ public function isNotEmpty() /** * Run a map over each nested chunk of items. * - * @param callable $callback - * @return static + * @template TMapSpreadValue + * + * @param callable(mixed): TMapSpreadValue $callback + * @return static */ public function mapSpread(callable $callback) { @@ -333,8 +341,11 @@ public function mapSpread(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback) { @@ -346,8 +357,11 @@ public function mapToGroups(callable $callback) /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback) { @@ -357,48 +371,42 @@ public function flatMap(callable $callback) /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class) { - return $this->map(function ($value, $key) use ($class) { - return new $class($value, $key); - }); + return $this->map(fn ($value, $key) => new $class($value, $key)); } /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null) { $callback = $this->valueRetriever($callback); - return $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $value) { - return is_null($result) || $value < $result ? $value : $result; - }); + return $this->map(fn ($value) => $callback($value)) + ->filter(fn ($value) => ! is_null($value)) + ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result); } /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null) { $callback = $this->valueRetriever($callback); - return $this->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $item) use ($callback) { + return $this->filter(fn ($value) => ! is_null($value))->reduce(function ($result, $item) use ($callback) { $value = $callback($item); return is_null($result) || $value > $result ? $value : $result; @@ -422,10 +430,10 @@ public function forPage($page, $perPage) /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key - * @param mixed $operator - * @param mixed $value - * @return static + * @param (callable(TValue, TKey): bool)|TValue|string $key + * @param TValue|string|null $operator + * @param TValue|null $value + * @return static, static> */ public function partition($key, $operator = null, $value = null) { @@ -450,7 +458,7 @@ public function partition($key, $operator = null, $value = null) /** * Get the sum of the given values. * - * @param callable|string|null $callback + * @param (callable(TValue): mixed)|string|null $callback * @return mixed */ public function sum($callback = null) @@ -459,40 +467,17 @@ public function sum($callback = null) ? $this->identity() : $this->valueRetriever($callback); - return $this->reduce(function ($result, $item) use ($callback) { - return $result + $callback($item); - }, 0); - } - - /** - * Apply the callback if the value is truthy. - * - * @param bool|mixed $value - * @param callable|null $callback - * @param callable|null $default - * @return static|mixed - */ - public function when($value, callable $callback = null, callable $default = null) - { - if (! $callback) { - return new HigherOrderWhenProxy($this, $value); - } - - if ($value) { - return $callback($this, $value); - } elseif ($default) { - return $default($this, $value); - } - - return $this; + return $this->reduce(fn ($result, $item) => $result + $callback($item), 0); } /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null) { @@ -502,34 +487,25 @@ public function whenEmpty(callable $callback, callable $default = null) /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } - /** - * Apply the callback if the value is falsy. - * - * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed - */ - public function unless($value, callable $callback, callable $default = null) - { - return $this->when(! $value, $callback, $default); - } - /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null) { @@ -539,9 +515,11 @@ public function unlessEmpty(callable $callback, callable $default = null) /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null) { @@ -551,7 +529,7 @@ public function unlessNotEmpty(callable $callback, callable $default = null) /** * Filter items by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value * @return static @@ -599,7 +577,7 @@ public function whereStrict($key, $value) * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -607,16 +585,14 @@ public function whereIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); - return $this->filter(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values) @@ -628,7 +604,7 @@ public function whereInStrict($key, $values) * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values) @@ -640,21 +616,21 @@ public function whereBetween($key, $values) * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values) { - return $this->filter(function ($item) use ($key, $values) { - return data_get($item, $key) < reset($values) || data_get($item, $key) > end($values); - }); + return $this->filter( + fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values) + ); } /** * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -662,16 +638,14 @@ public function whereNotIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); - return $this->reject(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values) @@ -682,8 +656,10 @@ public function whereNotInStrict($key, $values) /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type) { @@ -705,8 +681,10 @@ public function whereInstanceOf($type) /** * Pass the collection to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback) { @@ -716,7 +694,7 @@ public function pipe(callable $callback) /** * Pass the collection into a new class. * - * @param string $class + * @param class-string $class * @return mixed */ public function pipeInto($class) @@ -727,38 +705,26 @@ public function pipeInto($class) /** * Pass the collection through a series of callable pipes and return the result. * - * @param array $pipes + * @param array $callbacks * @return mixed */ - public function pipeThrough($pipes) + public function pipeThrough($callbacks) { - return static::make($pipes)->reduce( - function ($carry, $pipe) { - return $pipe($carry); - }, + return Collection::make($callbacks)->reduce( + fn ($carry, $callback) => $callback($carry), $this, ); } - /** - * Pass the collection to the given callback and then return it. - * - * @param callable $callback - * @return $this - */ - public function tap(callable $callback) - { - $callback(clone $this); - - return $this; - } - /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null) { @@ -771,22 +737,6 @@ public function reduce(callable $callback, $initial = null) return $result; } - /** - * Reduce the collection to multiple aggregate values. - * - * @param callable $callback - * @param mixed ...$initial - * @return array - * - * @deprecated Use "reduceSpread" instead - * - * @throws \UnexpectedValueException - */ - public function reduceMany(callable $callback, ...$initial) - { - return $this->reduceSpread($callback, ...$initial); - } - /** * Reduce the collection to multiple aggregate values. * @@ -805,7 +755,7 @@ public function reduceSpread(callable $callback, ...$initial) if (! is_array($result)) { throw new UnexpectedValueException(sprintf( - "%s::reduceMany expects reducer to return an array, but got a '%s' instead.", + "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.", class_basename(static::class), gettype($result) )); } @@ -814,22 +764,10 @@ class_basename(static::class), gettype($result) return $result; } - /** - * Reduce an associative collection to a single value. - * - * @param callable $callback - * @param mixed $initial - * @return mixed - */ - public function reduceWithKeys(callable $callback, $initial = null) - { - return $this->reduce($callback, $initial); - } - /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true) @@ -843,10 +781,45 @@ public function reject($callback = true) }); } + /** + * Pass the collection to the given callback and then return it. + * + * @param callable($this): mixed $callback + * @return $this + */ + public function tap(callable $callback) + { + $callback($this); + + return $this; + } + + /** + * Return only unique items from the collection array. + * + * @param (callable(TValue, TKey): mixed)|string|null $key + * @param bool $strict + * @return static + */ + public function unique($key = null, $strict = false) + { + $callback = $this->valueRetriever($key); + + $exists = []; + + return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { + if (in_array($id = $callback($item, $key), $exists, $strict)) { + return true; + } + + $exists[] = $id; + }); + } + /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null) @@ -857,7 +830,7 @@ public function uniqueStrict($key = null) /** * Collect the values into a collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect() { @@ -867,22 +840,19 @@ public function collect() /** * Get the collection of items as a plain array. * - * @return array + * @return array */ public function toArray() { - return $this->map(function ($value) { - return $value instanceof Arrayable ? $value->toArray() : $value; - })->all(); + return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all(); } /** * Convert the object into something JSON serializable. * - * @return array + * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return array_map(function ($value) { if ($value instanceof JsonSerializable) { @@ -976,7 +946,7 @@ public function __get($key) * Results array of items from Collection or Arrayable. * * @param mixed $items - * @return array + * @return array */ protected function getArrayableItems($items) { @@ -986,12 +956,12 @@ protected function getArrayableItems($items) return $items->all(); } elseif ($items instanceof Arrayable) { return $items->toArray(); + } elseif ($items instanceof Traversable) { + return iterator_to_array($items); } elseif ($items instanceof Jsonable) { return json_decode($items->toJson(), true); } elseif ($items instanceof JsonSerializable) { return (array) $items->jsonSerialize(); - } elseif ($items instanceof Traversable) { - return iterator_to_array($items); } elseif ($items instanceof UnitEnum) { return [$items]; } @@ -1002,13 +972,17 @@ protected function getArrayableItems($items) /** * Get an operator checker callback. * - * @param string $key + * @param callable|string $key * @param string|null $operator * @param mixed $value * @return \Closure */ protected function operatorForWhere($key, $operator = null, $value = null) { + if ($this->useAsCallable($key)) { + return $key; + } + if (func_num_args() === 1) { $value = true; @@ -1044,6 +1018,7 @@ protected function operatorForWhere($key, $operator = null, $value = null) case '>=': return $retrieved >= $value; case '===': return $retrieved === $value; case '!==': return $retrieved !== $value; + case '<=>': return $retrieved <=> $value; } }; } @@ -1071,22 +1046,18 @@ protected function valueRetriever($value) return $value; } - return function ($item) use ($value) { - return data_get($item, $value); - }; + return fn ($item) => data_get($item, $value); } /** * Make a function to check an item's equality. * * @param mixed $value - * @return \Closure + * @return \Closure(mixed): bool */ protected function equality($value) { - return function ($item) use ($value) { - return $item === $value; - }; + return fn ($item) => $item === $value; } /** @@ -1097,20 +1068,16 @@ protected function equality($value) */ protected function negate(Closure $callback) { - return function (...$params) use ($callback) { - return ! $callback(...$params); - }; + return fn (...$params) => ! $callback(...$params); } /** * Make a function that returns what's passed to it. * - * @return \Closure + * @return \Closure(TValue): TValue */ protected function identity() { - return function ($value) { - return $value; - }; + return fn ($value) => $value; } } diff --git a/lam/lib/3rdParty/composer/illuminate/collections/composer.json b/lam/lib/3rdParty/composer/illuminate/collections/composer.json index ecc453726..cc9aad342 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/composer.json +++ b/lam/lib/3rdParty/composer/illuminate/collections/composer.json @@ -14,9 +14,10 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0" + "php": "^8.0.2", + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0" }, "autoload": { "psr-4": { @@ -28,11 +29,11 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.0)." }, "config": { "sort-packages": true diff --git a/lam/lib/3rdParty/composer/illuminate/collections/helpers.php b/lam/lib/3rdParty/composer/illuminate/collections/helpers.php index 67669e5ce..9babf4e0f 100644 --- a/lam/lib/3rdParty/composer/illuminate/collections/helpers.php +++ b/lam/lib/3rdParty/composer/illuminate/collections/helpers.php @@ -7,10 +7,13 @@ /** * Create a collection from the given value. * - * @param mixed $value - * @return \Illuminate\Support\Collection + * @template TKey of array-key + * @template TValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $value + * @return \Illuminate\Support\Collection */ - function collect($value = null) + function collect($value = []) { return new Collection($value); } @@ -58,7 +61,7 @@ function data_get($target, $key, $default = null) if ($segment === '*') { if ($target instanceof Collection) { $target = $target->all(); - } elseif (! is_array($target)) { + } elseif (! is_iterable($target)) { return value($default); } @@ -177,6 +180,7 @@ function last($array) * Return the default value of the given value. * * @param mixed $value + * @param mixed ...$args * @return mixed */ function value($value, ...$args) diff --git a/lam/lib/3rdParty/composer/illuminate/conditionable/HigherOrderWhenProxy.php b/lam/lib/3rdParty/composer/illuminate/conditionable/HigherOrderWhenProxy.php new file mode 100644 index 000000000..579114cf1 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/conditionable/HigherOrderWhenProxy.php @@ -0,0 +1,109 @@ +target = $target; + } + + /** + * Set the condition on the proxy. + * + * @param bool $condition + * @return $this + */ + public function condition($condition) + { + [$this->condition, $this->hasCondition] = [$condition, true]; + + return $this; + } + + /** + * Indicate that the condition should be negated. + * + * @return $this + */ + public function negateConditionOnCapture() + { + $this->negateConditionOnCapture = true; + + return $this; + } + + /** + * Proxy accessing an attribute onto the target. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + if (! $this->hasCondition) { + $condition = $this->target->{$key}; + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$key} + : $this->target; + } + + /** + * Proxy a method call on the target. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (! $this->hasCondition) { + $condition = $this->target->{$method}(...$parameters); + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$method}(...$parameters) + : $this->target; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/mime/LICENSE b/lam/lib/3rdParty/composer/illuminate/conditionable/LICENSE.md similarity index 83% rename from lam/lib/3rdParty/composer/symfony/mime/LICENSE rename to lam/lib/3rdParty/composer/illuminate/conditionable/LICENSE.md index 4dd83ce0f..79810c848 100644 --- a/lam/lib/3rdParty/composer/symfony/mime/LICENSE +++ b/lam/lib/3rdParty/composer/illuminate/conditionable/LICENSE.md @@ -1,14 +1,16 @@ -Copyright (c) 2010-present Fabien Potencier +The MIT License (MIT) + +Copyright (c) Taylor Otwell 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: +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 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, diff --git a/lam/lib/3rdParty/composer/illuminate/conditionable/Traits/Conditionable.php b/lam/lib/3rdParty/composer/illuminate/conditionable/Traits/Conditionable.php new file mode 100644 index 000000000..19307437c --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/conditionable/Traits/Conditionable.php @@ -0,0 +1,73 @@ +condition($value); + } + + if ($value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } + + /** + * Apply the callback if the given "value" is (or resolves to) falsy. + * + * @template TUnlessParameter + * @template TUnlessReturnType + * + * @param (\Closure($this): TUnlessParameter)|TUnlessParameter|null $value + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $callback + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType + */ + public function unless($value = null, callable $callback = null, callable $default = null) + { + $value = $value instanceof Closure ? $value($this) : $value; + + if (func_num_args() === 0) { + return (new HigherOrderWhenProxy($this))->negateConditionOnCapture(); + } + + if (func_num_args() === 1) { + return (new HigherOrderWhenProxy($this))->condition(! $value); + } + + if (! $value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } +} diff --git a/lam/lib/3rdParty/composer/illuminate/conditionable/composer.json b/lam/lib/3rdParty/composer/illuminate/conditionable/composer.json new file mode 100644 index 000000000..a423aad17 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/conditionable/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/conditionable", + "description": "The Illuminate Conditionable package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.0.2" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Auth/Guard.php b/lam/lib/3rdParty/composer/illuminate/contracts/Auth/Guard.php index 2a27fb5f5..2796f1ae6 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Auth/Guard.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Auth/Guard.php @@ -40,6 +40,13 @@ public function id(); */ public function validate(array $credentials = []); + /** + * Determine if the guard has a user instance. + * + * @return bool + */ + public function hasUser(); + /** * Set the current user. * diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Auth/PasswordBrokerFactory.php b/lam/lib/3rdParty/composer/illuminate/contracts/Auth/PasswordBrokerFactory.php index 47b1c0896..683a90308 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Auth/PasswordBrokerFactory.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Auth/PasswordBrokerFactory.php @@ -8,7 +8,7 @@ interface PasswordBrokerFactory * Get a password broker instance by name. * * @param string|null $name - * @return mixed + * @return \Illuminate\Contracts\Auth\PasswordBroker */ public function broker($name = null); } diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/Broadcaster.php b/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/Broadcaster.php index 1034e4406..2d317d0a6 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/Broadcaster.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/Broadcaster.php @@ -28,6 +28,8 @@ public function validAuthenticationResponse($request, $result); * @param string $event * @param array $payload * @return void + * + * @throws \Illuminate\Broadcasting\BroadcastException */ public function broadcast(array $channels, $event, array $payload = []); } diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/ShouldBeUnique.php b/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/ShouldBeUnique.php new file mode 100644 index 000000000..c72b7a800 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Broadcasting/ShouldBeUnique.php @@ -0,0 +1,8 @@ +|CastsAttributes|CastsInboundAttributes */ public static function castUsing(array $arguments); } diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Database/Eloquent/CastsAttributes.php b/lam/lib/3rdParty/composer/illuminate/contracts/Database/Eloquent/CastsAttributes.php index 808d005f5..878169c05 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Database/Eloquent/CastsAttributes.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Database/Eloquent/CastsAttributes.php @@ -2,6 +2,10 @@ namespace Illuminate\Contracts\Database\Eloquent; +/** + * @template TGet + * @template TSet + */ interface CastsAttributes { /** @@ -11,7 +15,7 @@ interface CastsAttributes * @param string $key * @param mixed $value * @param array $attributes - * @return mixed + * @return TGet|null */ public function get($model, string $key, $value, array $attributes); @@ -20,7 +24,7 @@ public function get($model, string $key, $value, array $attributes); * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key - * @param mixed $value + * @param TSet|null $value * @param array $attributes * @return mixed */ diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Database/ModelIdentifier.php b/lam/lib/3rdParty/composer/illuminate/contracts/Database/ModelIdentifier.php index 9893d280e..aacd18c07 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Database/ModelIdentifier.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Database/ModelIdentifier.php @@ -34,6 +34,13 @@ class ModelIdentifier */ public $connection; + /** + * The class name of the model collection. + * + * @var string|null + */ + public $collectionClass; + /** * Create a new model identifier. * @@ -50,4 +57,17 @@ public function __construct($class, $id, array $relations, $connection) $this->relations = $relations; $this->connection = $connection; } + + /** + * Specify the collection class that should be used when serializing / restoring collections. + * + * @param string|null $collectionClass + * @return $this + */ + public function useCollectionClass(?string $collectionClass) + { + $this->collectionClass = $collectionClass; + + return $this; + } } diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Database/Query/Builder.php b/lam/lib/3rdParty/composer/illuminate/contracts/Database/Query/Builder.php new file mode 100644 index 000000000..e116ebf41 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Database/Query/Builder.php @@ -0,0 +1,12 @@ + */ public function getQueueableIds(); /** * Get the relationships of the entities being queued. * - * @return array + * @return array */ public function getQueueableRelations(); diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Routing/ResponseFactory.php b/lam/lib/3rdParty/composer/illuminate/contracts/Routing/ResponseFactory.php index 86c16cab8..a6206a9c4 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Routing/ResponseFactory.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Routing/ResponseFactory.php @@ -60,7 +60,7 @@ public function jsonp($callback, $data = [], $status = 200, array $headers = [], /** * Create a new streamed response instance. * - * @param \Closure $callback + * @param callable $callback * @param int $status * @param array $headers * @return \Symfony\Component\HttpFoundation\StreamedResponse @@ -70,7 +70,7 @@ public function stream($callback, $status = 200, array $headers = []); /** * Create a new streamed response instance as a file download. * - * @param \Closure $callback + * @param callable $callback * @param string|null $name * @param array $headers * @param string|null $disposition diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Routing/UrlGenerator.php b/lam/lib/3rdParty/composer/illuminate/contracts/Routing/UrlGenerator.php index e576dda19..cca221cc7 100644 --- a/lam/lib/3rdParty/composer/illuminate/contracts/Routing/UrlGenerator.php +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Routing/UrlGenerator.php @@ -69,6 +69,13 @@ public function route($name, $parameters = [], $absolute = true); */ public function action($action, $parameters = [], $absolute = true); + /** + * Get the root controller namespace. + * + * @return string + */ + public function getRootControllerNamespace(); + /** * Set the root controller namespace. * diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Session/Middleware/AuthenticatesSessions.php b/lam/lib/3rdParty/composer/illuminate/contracts/Session/Middleware/AuthenticatesSessions.php new file mode 100644 index 000000000..113f42007 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Session/Middleware/AuthenticatesSessions.php @@ -0,0 +1,8 @@ + */ public function toArray(); } diff --git a/lam/lib/3rdParty/composer/illuminate/contracts/Validation/InvokableRule.php b/lam/lib/3rdParty/composer/illuminate/contracts/Validation/InvokableRule.php new file mode 100644 index 000000000..b70330967 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/contracts/Validation/InvokableRule.php @@ -0,0 +1,16 @@ +path() - .(Str::contains($this->path(), '?') ? '&' : '?') + .(str_contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } @@ -523,8 +524,7 @@ public static function viewFactory() * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->items->getIterator(); } @@ -554,8 +554,7 @@ public function isNotEmpty() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->items->count(); } @@ -599,8 +598,7 @@ public function getOptions() * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->items->has($key); } @@ -611,8 +609,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items->get($key); } @@ -624,8 +621,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->items->put($key, $value); } @@ -636,8 +632,7 @@ public function offsetSet($key, $value) * @param mixed $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->items->forget($key); } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/AbstractPaginator.php b/lam/lib/3rdParty/composer/illuminate/pagination/AbstractPaginator.php index ac9ef4035..a4979840f 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/AbstractPaginator.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/AbstractPaginator.php @@ -6,9 +6,9 @@ use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\Arr; use Illuminate\Support\Collection; -use Illuminate\Support\Str; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Tappable; +use Traversable; /** * @mixin \Illuminate\Support\Collection @@ -181,7 +181,7 @@ public function url($page) } return $this->path() - .(Str::contains($this->path(), '?') ? '&' : '?') + .(str_contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } @@ -609,8 +609,7 @@ public static function useTailwind() */ public static function useBootstrap() { - static::defaultView('pagination::bootstrap-4'); - static::defaultSimpleView('pagination::simple-bootstrap-4'); + static::useBootstrapFour(); } /** @@ -624,13 +623,34 @@ public static function useBootstrapThree() static::defaultSimpleView('pagination::simple-default'); } + /** + * Indicate that Bootstrap 4 styling should be used for generated links. + * + * @return void + */ + public static function useBootstrapFour() + { + static::defaultView('pagination::bootstrap-4'); + static::defaultSimpleView('pagination::simple-bootstrap-4'); + } + + /** + * Indicate that Bootstrap 5 styling should be used for generated links. + * + * @return void + */ + public static function useBootstrapFive() + { + static::defaultView('pagination::bootstrap-5'); + static::defaultSimpleView('pagination::simple-bootstrap-5'); + } + /** * Get an iterator for the items. * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->items->getIterator(); } @@ -660,8 +680,7 @@ public function isNotEmpty() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->items->count(); } @@ -705,8 +724,7 @@ public function getOptions() * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->items->has($key); } @@ -717,8 +735,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items->get($key); } @@ -730,8 +747,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->items->put($key, $value); } @@ -742,8 +758,7 @@ public function offsetSet($key, $value) * @param mixed $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->items->forget($key); } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/Cursor.php b/lam/lib/3rdParty/composer/illuminate/pagination/Cursor.php index e8edf6526..1d622808b 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/Cursor.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/Cursor.php @@ -113,7 +113,7 @@ public function encode() */ public static function fromEncoded($encodedString) { - if (is_null($encodedString) || ! is_string($encodedString)) { + if (! is_string($encodedString)) { return null; } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/CursorPaginationException.php b/lam/lib/3rdParty/composer/illuminate/pagination/CursorPaginationException.php deleted file mode 100644 index b12ca607f..000000000 --- a/lam/lib/3rdParty/composer/illuminate/pagination/CursorPaginationException.php +++ /dev/null @@ -1,13 +0,0 @@ -{$key} = $value; } - $this->perPage = $perPage; + $this->perPage = (int) $perPage; $this->cursor = $cursor; $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; @@ -121,6 +121,16 @@ public function onFirstPage() return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore); } + /** + * Determine if the paginator is on the last page. + * + * @return bool + */ + public function onLastPage() + { + return ! $this->hasMorePages(); + } + /** * Get the instance as an array. * @@ -132,7 +142,9 @@ public function toArray() 'data' => $this->items->toArray(), 'path' => $this->path(), 'per_page' => $this->perPage(), + 'next_cursor' => $this->nextCursor()?->encode(), 'next_page_url' => $this->nextPageUrl(), + 'prev_cursor' => $this->previousCursor()?->encode(), 'prev_page_url' => $this->previousPageUrl(), ]; } @@ -142,8 +154,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/LengthAwarePaginator.php b/lam/lib/3rdParty/composer/illuminate/pagination/LengthAwarePaginator.php index 24f68b121..8d3e0ab77 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/LengthAwarePaginator.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/LengthAwarePaginator.php @@ -46,7 +46,7 @@ public function __construct($items, $total, $perPage, $currentPage = null, array } $this->total = $total; - $this->perPage = $perPage; + $this->perPage = (int) $perPage; $this->lastPage = max((int) ceil($total / $perPage), 1); $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName); @@ -213,8 +213,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/PaginationState.php b/lam/lib/3rdParty/composer/illuminate/pagination/PaginationState.php index ff8150ff2..347c6e224 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/PaginationState.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/PaginationState.php @@ -12,13 +12,9 @@ class PaginationState */ public static function resolveUsing($app) { - Paginator::viewFactoryResolver(function () use ($app) { - return $app['view']; - }); + Paginator::viewFactoryResolver(fn () => $app['view']); - Paginator::currentPathResolver(function () use ($app) { - return $app['request']->url(); - }); + Paginator::currentPathResolver(fn () => $app['request']->url()); Paginator::currentPageResolver(function ($pageName = 'page') use ($app) { $page = $app['request']->input($pageName); @@ -30,9 +26,7 @@ public static function resolveUsing($app) return 1; }); - Paginator::queryStringResolver(function () use ($app) { - return $app['request']->query(); - }); + Paginator::queryStringResolver(fn () => $app['request']->query()); CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) { return Cursor::fromEncoded($app['request']->input($cursorName)); diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/Paginator.php b/lam/lib/3rdParty/composer/illuminate/pagination/Paginator.php index 733edb8e0..d307ee9ff 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/Paginator.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/Paginator.php @@ -158,8 +158,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/UrlWindow.php b/lam/lib/3rdParty/composer/illuminate/pagination/UrlWindow.php index 31c7cc2a4..99286f7b3 100644 --- a/lam/lib/3rdParty/composer/illuminate/pagination/UrlWindow.php +++ b/lam/lib/3rdParty/composer/illuminate/pagination/UrlWindow.php @@ -100,7 +100,7 @@ protected function getUrlSlider($onEachSide) } /** - * Get the slider of URLs when too close to beginning of window. + * Get the slider of URLs when too close to the beginning of the window. * * @param int $window * @param int $onEachSide @@ -116,7 +116,7 @@ protected function getSliderTooCloseToBeginning($window, $onEachSide) } /** - * Get the slider of URLs when too close to ending of window. + * Get the slider of URLs when too close to the ending of the window. * * @param int $window * @param int $onEachSide diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/composer.json b/lam/lib/3rdParty/composer/illuminate/pagination/composer.json index 5c8a380b2..1b054f5b9 100755 --- a/lam/lib/3rdParty/composer/illuminate/pagination/composer.json +++ b/lam/lib/3rdParty/composer/illuminate/pagination/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": "^7.3|^8.0", - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.0.2", + "ext-filter": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0" }, "autoload": { "psr-4": { @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "config": { diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/bootstrap-5.blade.php b/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/bootstrap-5.blade.php new file mode 100644 index 000000000..a1795a4d8 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/bootstrap-5.blade.php @@ -0,0 +1,88 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php b/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php new file mode 100644 index 000000000..a89005ee7 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php @@ -0,0 +1,29 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/lam/lib/3rdParty/composer/illuminate/support/Benchmark.php b/lam/lib/3rdParty/composer/illuminate/support/Benchmark.php new file mode 100644 index 000000000..3a09d5920 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/support/Benchmark.php @@ -0,0 +1,50 @@ +map(function ($callback) use ($iterations) { + return collect(range(1, $iterations))->map(function () use ($callback) { + gc_collect_cycles(); + + $start = hrtime(true); + + $callback(); + + return (hrtime(true) - $start) / 1000000; + })->average(); + })->when( + $benchmarkables instanceof Closure, + fn ($c) => $c->first(), + fn ($c) => $c->all(), + ); + } + + /** + * Measure a callable or array of callables over the given number of iterations, then dump and die. + * + * @param \Closure|array $benchmarkables + * @param int $iterations + * @return never + */ + public static function dd(Closure|array $benchmarkables, int $iterations = 1): void + { + $result = collect(static::measure(Arr::wrap($benchmarkables), $iterations)) + ->map(fn ($average) => number_format($average, 3).'ms') + ->when($benchmarkables instanceof Closure, fn ($c) => $c->first(), fn ($c) => $c->all()); + + dd($result); + } +} diff --git a/lam/lib/3rdParty/composer/illuminate/support/Carbon.php b/lam/lib/3rdParty/composer/illuminate/support/Carbon.php index 004b27b07..972d7eb72 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Carbon.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Carbon.php @@ -4,9 +4,12 @@ use Carbon\Carbon as BaseCarbon; use Carbon\CarbonImmutable as BaseCarbonImmutable; +use Illuminate\Support\Traits\Conditionable; class Carbon extends BaseCarbon { + use Conditionable; + /** * {@inheritdoc} */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Composer.php b/lam/lib/3rdParty/composer/illuminate/support/Composer.php index 623e9163d..9933615cb 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Composer.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Composer.php @@ -65,7 +65,7 @@ public function dumpOptimized() * * @return array */ - protected function findComposer() + public function findComposer() { if ($this->files->exists($this->workingPath.'/composer.phar')) { return [$this->phpBinary(), 'composer.phar']; @@ -107,4 +107,26 @@ public function setWorkingPath($path) return $this; } + + /** + * Get the version of Composer. + * + * @return string|null + */ + public function getVersion() + { + $command = array_merge($this->findComposer(), ['-V', '--no-ansi']); + + $process = $this->getProcess($command); + + $process->run(); + + $output = $process->getOutput(); + + if (preg_match('/(\d+(\.\d+){2})/', $output, $version)) { + return $version[1]; + } + + return explode(' ', $output)[2] ?? null; + } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/ConfigurationUrlParser.php b/lam/lib/3rdParty/composer/illuminate/support/ConfigurationUrlParser.php index be54b9a83..a1b933709 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/ConfigurationUrlParser.php +++ b/lam/lib/3rdParty/composer/illuminate/support/ConfigurationUrlParser.php @@ -67,9 +67,7 @@ protected function getPrimaryOptions($url) 'port' => $url['port'] ?? null, 'username' => $url['user'] ?? null, 'password' => $url['pass'] ?? null, - ], function ($value) { - return ! is_null($value); - }); + ], fn ($value) => ! is_null($value)); } /** diff --git a/lam/lib/3rdParty/composer/illuminate/support/DateFactory.php b/lam/lib/3rdParty/composer/illuminate/support/DateFactory.php index f36cb46f3..3d0cd04df 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/DateFactory.php +++ b/lam/lib/3rdParty/composer/illuminate/support/DateFactory.php @@ -9,77 +9,77 @@ * @see https://carbon.nesbot.com/docs/ * @see https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Factory.php * - * @method static Carbon create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $tz = null) - * @method static Carbon createFromDate($year = null, $month = null, $day = null, $tz = null) - * @method static Carbon|false createFromFormat($format, $time, $tz = null) - * @method static Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $tz = null) - * @method static Carbon createFromTimeString($time, $tz = null) - * @method static Carbon createFromTimestamp($timestamp, $tz = null) - * @method static Carbon createFromTimestampMs($timestamp, $tz = null) - * @method static Carbon createFromTimestampUTC($timestamp) - * @method static Carbon createMidnightDate($year = null, $month = null, $day = null, $tz = null) - * @method static Carbon|false createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null) - * @method static Carbon disableHumanDiffOption($humanDiffOption) - * @method static Carbon enableHumanDiffOption($humanDiffOption) - * @method static mixed executeWithLocale($locale, $func) - * @method static Carbon fromSerialized($value) - * @method static array getAvailableLocales() - * @method static array getDays() - * @method static int getHumanDiffOptions() - * @method static array getIsoUnits() - * @method static Carbon getLastErrors() - * @method static string getLocale() - * @method static int getMidDayAt() - * @method static Carbon getTestNow() - * @method static \Symfony\Component\Translation\TranslatorInterface getTranslator() - * @method static int getWeekEndsAt() - * @method static int getWeekStartsAt() - * @method static array getWeekendDays() - * @method static bool hasFormat($date, $format) - * @method static bool hasMacro($name) - * @method static bool hasRelativeKeywords($time) - * @method static bool hasTestNow() - * @method static Carbon instance($date) - * @method static bool isImmutable() - * @method static bool isModifiableUnit($unit) - * @method static Carbon isMutable() - * @method static bool isStrictModeEnabled() - * @method static bool localeHasDiffOneDayWords($locale) - * @method static bool localeHasDiffSyntax($locale) - * @method static bool localeHasDiffTwoDayWords($locale) - * @method static bool localeHasPeriodSyntax($locale) - * @method static bool localeHasShortUnits($locale) - * @method static void macro($name, $macro) - * @method static Carbon|null make($var) - * @method static Carbon maxValue() - * @method static Carbon minValue() - * @method static void mixin($mixin) - * @method static Carbon now($tz = null) - * @method static Carbon parse($time = null, $tz = null) - * @method static string pluralUnit(string $unit) - * @method static void resetMonthsOverflow() - * @method static void resetToStringFormat() - * @method static void resetYearsOverflow() - * @method static void serializeUsing($callback) - * @method static Carbon setHumanDiffOptions($humanDiffOptions) - * @method static bool setLocale($locale) - * @method static void setMidDayAt($hour) - * @method static void setTestNow($testNow = null) - * @method static void setToStringFormat($format) - * @method static void setTranslator(\Symfony\Component\Translation\TranslatorInterface $translator) - * @method static Carbon setUtf8($utf8) - * @method static void setWeekEndsAt($day) - * @method static void setWeekStartsAt($day) - * @method static void setWeekendDays($days) - * @method static bool shouldOverflowMonths() - * @method static bool shouldOverflowYears() - * @method static string singularUnit(string $unit) - * @method static Carbon today($tz = null) - * @method static Carbon tomorrow($tz = null) - * @method static void useMonthsOverflow($monthsOverflow = true) - * @method static Carbon useStrictMode($strictModeEnabled = true) - * @method static void useYearsOverflow($yearsOverflow = true) - * @method static Carbon yesterday($tz = null) + * @method \Illuminate\Support\Carbon create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $tz = null) + * @method \Illuminate\Support\Carbon createFromDate($year = null, $month = null, $day = null, $tz = null) + * @method \Illuminate\Support\Carbon|false createFromFormat($format, $time, $tz = null) + * @method \Illuminate\Support\Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $tz = null) + * @method \Illuminate\Support\Carbon createFromTimeString($time, $tz = null) + * @method \Illuminate\Support\Carbon createFromTimestamp($timestamp, $tz = null) + * @method \Illuminate\Support\Carbon createFromTimestampMs($timestamp, $tz = null) + * @method \Illuminate\Support\Carbon createFromTimestampUTC($timestamp) + * @method \Illuminate\Support\Carbon createMidnightDate($year = null, $month = null, $day = null, $tz = null) + * @method \Illuminate\Support\Carbon|false createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null) + * @method void disableHumanDiffOption($humanDiffOption) + * @method void enableHumanDiffOption($humanDiffOption) + * @method mixed executeWithLocale($locale, $func) + * @method \Illuminate\Support\Carbon fromSerialized($value) + * @method array getAvailableLocales() + * @method array getDays() + * @method int getHumanDiffOptions() + * @method array getIsoUnits() + * @method array getLastErrors() + * @method string getLocale() + * @method int getMidDayAt() + * @method \Illuminate\Support\Carbon|null getTestNow() + * @method \Symfony\Component\Translation\TranslatorInterface getTranslator() + * @method int getWeekEndsAt() + * @method int getWeekStartsAt() + * @method array getWeekendDays() + * @method bool hasFormat($date, $format) + * @method bool hasMacro($name) + * @method bool hasRelativeKeywords($time) + * @method bool hasTestNow() + * @method \Illuminate\Support\Carbon instance($date) + * @method bool isImmutable() + * @method bool isModifiableUnit($unit) + * @method bool isMutable() + * @method bool isStrictModeEnabled() + * @method bool localeHasDiffOneDayWords($locale) + * @method bool localeHasDiffSyntax($locale) + * @method bool localeHasDiffTwoDayWords($locale) + * @method bool localeHasPeriodSyntax($locale) + * @method bool localeHasShortUnits($locale) + * @method void macro($name, $macro) + * @method \Illuminate\Support\Carbon|null make($var) + * @method \Illuminate\Support\Carbon maxValue() + * @method \Illuminate\Support\Carbon minValue() + * @method void mixin($mixin) + * @method \Illuminate\Support\Carbon now($tz = null) + * @method \Illuminate\Support\Carbon parse($time = null, $tz = null) + * @method string pluralUnit(string $unit) + * @method void resetMonthsOverflow() + * @method void resetToStringFormat() + * @method void resetYearsOverflow() + * @method void serializeUsing($callback) + * @method void setHumanDiffOptions($humanDiffOptions) + * @method bool setLocale($locale) + * @method void setMidDayAt($hour) + * @method void setTestNow($testNow = null) + * @method void setToStringFormat($format) + * @method void setTranslator(\Symfony\Component\Translation\TranslatorInterface $translator) + * @method void setUtf8($utf8) + * @method void setWeekEndsAt($day) + * @method void setWeekStartsAt($day) + * @method void setWeekendDays($days) + * @method bool shouldOverflowMonths() + * @method bool shouldOverflowYears() + * @method string singularUnit(string $unit) + * @method \Illuminate\Support\Carbon today($tz = null) + * @method \Illuminate\Support\Carbon tomorrow($tz = null) + * @method void useMonthsOverflow($monthsOverflow = true) + * @method void useStrictMode($strictModeEnabled = true) + * @method void useYearsOverflow($yearsOverflow = true) + * @method \Illuminate\Support\Carbon yesterday($tz = null) */ class DateFactory { @@ -211,7 +211,7 @@ public function __call($method, $parameters) $dateClass = static::$dateClass ?: $defaultClassName; - // Check if date can be created using public class method... + // Check if the date can be created using the public class method... if (method_exists($dateClass, $method) || method_exists($dateClass, 'hasMacro') && $dateClass::hasMacro($method)) { return $dateClass::$method(...$parameters); diff --git a/lam/lib/3rdParty/composer/illuminate/support/Env.php b/lam/lib/3rdParty/composer/illuminate/support/Env.php index b31007304..4d5747a8a 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Env.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Env.php @@ -96,8 +96,6 @@ public static function get($key, $default = null) return $value; }) - ->getOrCall(function () use ($default) { - return value($default); - }); + ->getOrCall(fn () => value($default)); } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Exceptions/MathException.php b/lam/lib/3rdParty/composer/illuminate/support/Exceptions/MathException.php new file mode 100644 index 000000000..6f9158df0 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/support/Exceptions/MathException.php @@ -0,0 +1,10 @@ +shouldReceive(...func_get_args()); } + /** + * Initiate a mock expectation on the facade. + * + * @return \Mockery\Expectation + */ + public static function expects() + { + $name = static::getFacadeAccessor(); + + $mock = static::isMock() + ? static::$resolvedInstance[$name] + : static::createFreshMockInstance(); + + return $mock->expects(...func_get_args()); + } + /** * Create a fresh mock instance for the given class. * @@ -181,21 +208,21 @@ protected static function getFacadeAccessor() /** * Resolve the facade root instance from the container. * - * @param object|string $name + * @param string $name * @return mixed */ protected static function resolveFacadeInstance($name) { - if (is_object($name)) { - return $name; - } - if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } if (static::$app) { - return static::$resolvedInstance[$name] = static::$app[$name]; + if (static::$cached) { + return static::$resolvedInstance[$name] = static::$app[$name]; + } + + return static::$app[$name]; } } @@ -220,6 +247,56 @@ public static function clearResolvedInstances() static::$resolvedInstance = []; } + /** + * Get the application default aliases. + * + * @return \Illuminate\Support\Collection + */ + public static function defaultAliases() + { + return collect([ + 'App' => App::class, + 'Arr' => Arr::class, + 'Artisan' => Artisan::class, + 'Auth' => Auth::class, + 'Blade' => Blade::class, + 'Broadcast' => Broadcast::class, + 'Bus' => Bus::class, + 'Cache' => Cache::class, + 'Config' => Config::class, + 'Cookie' => Cookie::class, + 'Crypt' => Crypt::class, + 'Date' => Date::class, + 'DB' => DB::class, + 'Eloquent' => Model::class, + 'Event' => Event::class, + 'File' => File::class, + 'Gate' => Gate::class, + 'Hash' => Hash::class, + 'Http' => Http::class, + 'Js' => Js::class, + 'Lang' => Lang::class, + 'Log' => Log::class, + 'Mail' => Mail::class, + 'Notification' => Notification::class, + 'Password' => Password::class, + 'Queue' => Queue::class, + 'RateLimiter' => RateLimiter::class, + 'Redirect' => Redirect::class, + 'Request' => Request::class, + 'Response' => Response::class, + 'Route' => Route::class, + 'Schema' => Schema::class, + 'Session' => Session::class, + 'Storage' => Storage::class, + 'Str' => Str::class, + 'URL' => URL::class, + 'Validator' => Validator::class, + 'View' => View::class, + 'Vite' => Vite::class, + ]); + } + /** * Get the application instance behind the facade. * diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/File.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/File.php index c22d363a8..7063fef41 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/File.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/File.php @@ -3,48 +3,57 @@ namespace Illuminate\Support\Facades; /** - * @method static \Symfony\Component\Finder\SplFileInfo[] allFiles(string $directory, bool $hidden = false) - * @method static \Symfony\Component\Finder\SplFileInfo[] files(string $directory, bool $hidden = false) - * @method static array directories(string $directory) - * @method static array glob(string $pattern, int $flags = 0) - * @method static bool cleanDirectory(string $directory) - * @method static bool copy(string $path, string $target) - * @method static bool copyDirectory(string $directory, string $destination, int|null $options = null) - * @method static bool delete(string|array $paths) - * @method static bool deleteDirectories(string $directory) - * @method static bool deleteDirectory(string $directory, bool $preserve = false) * @method static bool exists(string $path) - * @method static bool isDirectory(string $directory) - * @method static bool isFile(string $file) - * @method static bool isReadable(string $path) - * @method static bool isWritable(string $path) - * @method static bool makeDirectory(string $path, int $mode = 0755, bool $recursive = false, bool $force = false) * @method static bool missing(string $path) - * @method static bool move(string $path, string $target) - * @method static bool moveDirectory(string $from, string $to, bool $overwrite = false) - * @method static int append(string $path, string $data) - * @method static int lastModified(string $path) - * @method static int prepend(string $path, string $data) - * @method static int size(string $path) + * @method static string get(string $path, bool $lock = false) + * @method static string sharedGet(string $path) + * @method static mixed getRequire(string $path, array $data = []) + * @method static mixed requireOnce(string $path, array $data = []) + * @method static \Illuminate\Support\LazyCollection lines(string $path) + * @method static string hash(string $path, string $algorithm = 'md5') * @method static int|bool put(string $path, string $contents, bool $lock = false) + * @method static void replace(string $path, string $content, int|null $mode = null) + * @method static void replaceInFile(array|string $search, array|string $replace, string $path) + * @method static int prepend(string $path, string $data) + * @method static int append(string $path, string $data) * @method static mixed chmod(string $path, int|null $mode = null) - * @method static mixed getRequire(string $path, array $data = []) - * @method static mixed requireOnce(string $file, array $data = []) + * @method static bool delete(string|array $paths) + * @method static bool move(string $path, string $target) + * @method static bool copy(string $path, string $target) + * @method static void link(string $target, string $link) + * @method static void relativeLink(string $target, string $link) + * @method static string name(string $path) * @method static string basename(string $path) * @method static string dirname(string $path) * @method static string extension(string $path) - * @method static string get(string $path, bool $lock = false) - * @method static string hash(string $path) - * @method static string name(string $path) - * @method static string sharedGet(string $path) + * @method static string|null guessExtension(string $path) * @method static string type(string $path) * @method static string|false mimeType(string $path) - * @method static string|null guessExtension(string $path) + * @method static int size(string $path) + * @method static int lastModified(string $path) + * @method static bool isDirectory(string $directory) + * @method static bool isEmptyDirectory(string $directory, bool $ignoreDotFiles = false) + * @method static bool isReadable(string $path) + * @method static bool isWritable(string $path) + * @method static bool hasSameHash(string $firstFile, string $secondFile) + * @method static bool isFile(string $file) + * @method static array glob(string $pattern, int $flags = 0) + * @method static \Symfony\Component\Finder\SplFileInfo[] files(string $directory, bool $hidden = false) + * @method static \Symfony\Component\Finder\SplFileInfo[] allFiles(string $directory, bool $hidden = false) + * @method static array directories(string $directory) * @method static void ensureDirectoryExists(string $path, int $mode = 0755, bool $recursive = true) - * @method static void link(string $target, string $link) - * @method static \Illuminate\Support\LazyCollection lines(string $path) - * @method static void relativeLink(string $target, string $link) - * @method static void replace(string $path, string $content) + * @method static bool makeDirectory(string $path, int $mode = 0755, bool $recursive = false, bool $force = false) + * @method static bool moveDirectory(string $from, string $to, bool $overwrite = false) + * @method static bool copyDirectory(string $directory, string $destination, int|null $options = null) + * @method static bool deleteDirectory(string $directory, bool $preserve = false) + * @method static bool deleteDirectories(string $directory) + * @method static bool cleanDirectory(string $directory) + * @method static \Illuminate\Filesystem\Filesystem|mixed when(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) + * @method static \Illuminate\Filesystem\Filesystem|mixed unless(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Filesystem\Filesystem */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Gate.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Gate.php index 49d8b66d6..7cb4a525e 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Gate.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Gate.php @@ -5,26 +5,33 @@ use Illuminate\Contracts\Auth\Access\Gate as GateContract; /** - * @method static \Illuminate\Auth\Access\Gate guessPolicyNamesUsing(callable $callback) - * @method static \Illuminate\Auth\Access\Response authorize(string $ability, array|mixed $arguments = []) - * @method static \Illuminate\Auth\Access\Response inspect(string $ability, array|mixed $arguments = []) - * @method static \Illuminate\Auth\Access\Response allowIf(\Closure|bool $condition, string|null $message = null, mixed $code = null) - * @method static \Illuminate\Auth\Access\Response denyIf(\Closure|bool $condition, string|null $message = null, mixed $code = null) - * @method static \Illuminate\Contracts\Auth\Access\Gate after(callable $callback) - * @method static \Illuminate\Contracts\Auth\Access\Gate before(callable $callback) - * @method static \Illuminate\Contracts\Auth\Access\Gate define(string $ability, callable|string $callback) - * @method static \Illuminate\Contracts\Auth\Access\Gate forUser(\Illuminate\Contracts\Auth\Authenticatable|mixed $user) - * @method static \Illuminate\Contracts\Auth\Access\Gate policy(string $class, string $policy) - * @method static array abilities() + * @method static bool has(string|array $ability) + * @method static \Illuminate\Auth\Access\Response allowIf(\Illuminate\Auth\Access\Response|\Closure|bool $condition, string|null $message = null, string|null $code = null) + * @method static \Illuminate\Auth\Access\Response denyIf(\Illuminate\Auth\Access\Response|\Closure|bool $condition, string|null $message = null, string|null $code = null) + * @method static \Illuminate\Auth\Access\Gate define(string $ability, callable|array|string $callback) + * @method static \Illuminate\Auth\Access\Gate resource(string $name, string $class, array|null $abilities = null) + * @method static \Illuminate\Auth\Access\Gate policy(string $class, string $policy) + * @method static \Illuminate\Auth\Access\Gate before(callable $callback) + * @method static \Illuminate\Auth\Access\Gate after(callable $callback) * @method static bool allows(string $ability, array|mixed $arguments = []) - * @method static bool any(iterable|string $abilities, array|mixed $arguments = []) - * @method static bool check(iterable|string $abilities, array|mixed $arguments = []) * @method static bool denies(string $ability, array|mixed $arguments = []) - * @method static bool has(string $ability) - * @method static mixed getPolicyFor(object|string $class) + * @method static bool check(iterable|string $abilities, array|mixed $arguments = []) + * @method static bool any(iterable|string $abilities, array|mixed $arguments = []) + * @method static bool none(iterable|string $abilities, array|mixed $arguments = []) + * @method static \Illuminate\Auth\Access\Response authorize(string $ability, array|mixed $arguments = []) + * @method static \Illuminate\Auth\Access\Response inspect(string $ability, array|mixed $arguments = []) * @method static mixed raw(string $ability, array|mixed $arguments = []) + * @method static mixed getPolicyFor(object|string $class) + * @method static \Illuminate\Auth\Access\Gate guessPolicyNamesUsing(callable $callback) + * @method static mixed resolvePolicy(object|string $class) + * @method static \Illuminate\Auth\Access\Gate forUser(\Illuminate\Contracts\Auth\Authenticatable|mixed $user) + * @method static array abilities() + * @method static array policies() + * @method static \Illuminate\Auth\Access\Gate setContainer(\Illuminate\Contracts\Container\Container $container) + * @method static \Illuminate\Auth\Access\Response denyWithStatus(int $status, string|null $message = null, int|null $code = null) + * @method static \Illuminate\Auth\Access\Response denyAsNotFound(string|null $message = null, int|null $code = null) * - * @see \Illuminate\Contracts\Auth\Access\Gate + * @see \Illuminate\Auth\Access\Gate */ class Gate extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Hash.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Hash.php index b9855fdd7..1cfe56120 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Hash.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Hash.php @@ -3,13 +3,23 @@ namespace Illuminate\Support\Facades; /** + * @method static \Illuminate\Hashing\BcryptHasher createBcryptDriver() + * @method static \Illuminate\Hashing\ArgonHasher createArgonDriver() + * @method static \Illuminate\Hashing\Argon2IdHasher createArgon2idDriver() * @method static array info(string $hashedValue) + * @method static string make(string $value, array $options = []) * @method static bool check(string $value, string $hashedValue, array $options = []) * @method static bool needsRehash(string $hashedValue, array $options = []) - * @method static string make(string $value, array $options = []) - * @method static \Illuminate\Hashing\HashManager extend($driver, \Closure $callback) + * @method static string getDefaultDriver() + * @method static mixed driver(string|null $driver = null) + * @method static \Illuminate\Hashing\HashManager extend(string $driver, \Closure $callback) + * @method static array getDrivers() + * @method static \Illuminate\Contracts\Container\Container getContainer() + * @method static \Illuminate\Hashing\HashManager setContainer(\Illuminate\Contracts\Container\Container $container) + * @method static \Illuminate\Hashing\HashManager forgetDrivers() * * @see \Illuminate\Hashing\HashManager + * @see \Illuminate\Hashing\AbstractHasher */ class Hash extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Http.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Http.php index d6f2f6648..4aab84148 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Http.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Http.php @@ -5,51 +5,80 @@ use Illuminate\Http\Client\Factory; /** - * @method static \GuzzleHttp\Promise\PromiseInterface response($body = null, $status = 200, $headers = []) - * @method static \Illuminate\Http\Client\Factory fake($callback = null) - * @method static \Illuminate\Http\Client\PendingRequest accept(string $contentType) - * @method static \Illuminate\Http\Client\PendingRequest acceptJson() - * @method static \Illuminate\Http\Client\PendingRequest asForm() + * @method static \GuzzleHttp\Promise\PromiseInterface response(array|string|null $body = null, int $status = 200, array $headers = []) + * @method static \Illuminate\Http\Client\ResponseSequence sequence(array $responses = []) + * @method static \Illuminate\Http\Client\Factory allowStrayRequests() + * @method static void recordRequestResponsePair(\Illuminate\Http\Client\Request $request, \Illuminate\Http\Client\Response $response) + * @method static void assertSent(callable $callback) + * @method static void assertSentInOrder(array $callbacks) + * @method static void assertNotSent(callable $callback) + * @method static void assertNothingSent() + * @method static void assertSentCount(int $count) + * @method static void assertSequencesAreEmpty() + * @method static \Illuminate\Support\Collection recorded(callable $callback = null) + * @method static \Illuminate\Contracts\Events\Dispatcher|null getDispatcher() + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static mixed macroCall(string $method, array $parameters) + * @method static \Illuminate\Http\Client\PendingRequest baseUrl(string $url) + * @method static \Illuminate\Http\Client\PendingRequest withBody(string $content, string $contentType) * @method static \Illuminate\Http\Client\PendingRequest asJson() + * @method static \Illuminate\Http\Client\PendingRequest asForm() + * @method static \Illuminate\Http\Client\PendingRequest attach(string|array $name, string|resource $contents = '', string|null $filename = null, array $headers = []) * @method static \Illuminate\Http\Client\PendingRequest asMultipart() - * @method static \Illuminate\Http\Client\PendingRequest async() - * @method static \Illuminate\Http\Client\PendingRequest attach(string|array $name, string $contents = '', string|null $filename = null, array $headers = []) - * @method static \Illuminate\Http\Client\PendingRequest baseUrl(string $url) - * @method static \Illuminate\Http\Client\PendingRequest beforeSending(callable $callback) * @method static \Illuminate\Http\Client\PendingRequest bodyFormat(string $format) * @method static \Illuminate\Http\Client\PendingRequest contentType(string $contentType) - * @method static \Illuminate\Http\Client\PendingRequest dd() - * @method static \Illuminate\Http\Client\PendingRequest dump() - * @method static \Illuminate\Http\Client\PendingRequest retry(int $times, int $sleep = 0, ?callable $when = null) - * @method static \Illuminate\Http\Client\PendingRequest sink(string|resource $to) - * @method static \Illuminate\Http\Client\PendingRequest stub(callable $callback) - * @method static \Illuminate\Http\Client\PendingRequest timeout(int $seconds) + * @method static \Illuminate\Http\Client\PendingRequest acceptJson() + * @method static \Illuminate\Http\Client\PendingRequest accept(string $contentType) + * @method static \Illuminate\Http\Client\PendingRequest withHeaders(array $headers) * @method static \Illuminate\Http\Client\PendingRequest withBasicAuth(string $username, string $password) - * @method static \Illuminate\Http\Client\PendingRequest withBody(resource|string $content, string $contentType) - * @method static \Illuminate\Http\Client\PendingRequest withCookies(array $cookies, string $domain) * @method static \Illuminate\Http\Client\PendingRequest withDigestAuth(string $username, string $password) - * @method static \Illuminate\Http\Client\PendingRequest withHeaders(array $headers) - * @method static \Illuminate\Http\Client\PendingRequest withMiddleware(callable $middleware) - * @method static \Illuminate\Http\Client\PendingRequest withOptions(array $options) * @method static \Illuminate\Http\Client\PendingRequest withToken(string $token, string $type = 'Bearer') * @method static \Illuminate\Http\Client\PendingRequest withUserAgent(string $userAgent) + * @method static \Illuminate\Http\Client\PendingRequest withUrlParameters(array $parameters = []) + * @method static \Illuminate\Http\Client\PendingRequest withCookies(array $cookies, string $domain) + * @method static \Illuminate\Http\Client\PendingRequest maxRedirects(int $max) * @method static \Illuminate\Http\Client\PendingRequest withoutRedirecting() * @method static \Illuminate\Http\Client\PendingRequest withoutVerifying() - * @method static array pool(callable $callback) - * @method static \Illuminate\Http\Client\Response delete(string $url, array $data = []) + * @method static \Illuminate\Http\Client\PendingRequest sink(string|resource $to) + * @method static \Illuminate\Http\Client\PendingRequest timeout(int $seconds) + * @method static \Illuminate\Http\Client\PendingRequest connectTimeout(int $seconds) + * @method static \Illuminate\Http\Client\PendingRequest retry(int $times, int $sleepMilliseconds = 0, callable|null $when = null, bool $throw = true) + * @method static \Illuminate\Http\Client\PendingRequest withOptions(array $options) + * @method static \Illuminate\Http\Client\PendingRequest withMiddleware(callable $middleware) + * @method static \Illuminate\Http\Client\PendingRequest beforeSending(callable $callback) + * @method static \Illuminate\Http\Client\PendingRequest throw(callable|null $callback = null) + * @method static \Illuminate\Http\Client\PendingRequest throwIf(callable|bool $condition, callable|null $throwCallback = null) + * @method static \Illuminate\Http\Client\PendingRequest throwUnless(bool $condition) + * @method static \Illuminate\Http\Client\PendingRequest dump() + * @method static \Illuminate\Http\Client\PendingRequest dd() * @method static \Illuminate\Http\Client\Response get(string $url, array|string|null $query = null) * @method static \Illuminate\Http\Client\Response head(string $url, array|string|null $query = null) - * @method static \Illuminate\Http\Client\Response patch(string $url, array $data = []) * @method static \Illuminate\Http\Client\Response post(string $url, array $data = []) + * @method static \Illuminate\Http\Client\Response patch(string $url, array $data = []) * @method static \Illuminate\Http\Client\Response put(string $url, array $data = []) + * @method static \Illuminate\Http\Client\Response delete(string $url, array $data = []) + * @method static array pool(callable $callback) * @method static \Illuminate\Http\Client\Response send(string $method, string $url, array $options = []) - * @method static \Illuminate\Http\Client\ResponseSequence fakeSequence(string $urlPattern = '*') - * @method static void assertSent(callable $callback) - * @method static void assertSentInOrder(array $callbacks) - * @method static void assertNotSent(callable $callback) - * @method static void assertNothingSent() - * @method static void assertSentCount(int $count) - * @method static void assertSequencesAreEmpty() + * @method static \GuzzleHttp\Client buildClient() + * @method static \GuzzleHttp\Client createClient(\GuzzleHttp\HandlerStack $handlerStack) + * @method static \GuzzleHttp\HandlerStack buildHandlerStack() + * @method static \GuzzleHttp\HandlerStack pushHandlers(\GuzzleHttp\HandlerStack $handlerStack) + * @method static \Closure buildBeforeSendingHandler() + * @method static \Closure buildRecorderHandler() + * @method static \Closure buildStubHandler() + * @method static \GuzzleHttp\Psr7\RequestInterface runBeforeSendingCallbacks(\GuzzleHttp\Psr7\RequestInterface $request, array $options) + * @method static array mergeOptions(array ...$options) + * @method static \Illuminate\Http\Client\PendingRequest stub(callable $callback) + * @method static \Illuminate\Http\Client\PendingRequest async(bool $async = true) + * @method static \GuzzleHttp\Promise\PromiseInterface|null getPromise() + * @method static \Illuminate\Http\Client\PendingRequest setClient(\GuzzleHttp\Client $client) + * @method static \Illuminate\Http\Client\PendingRequest setHandler(callable $handler) + * @method static array getOptions() + * @method static \Illuminate\Http\Client\PendingRequest|mixed when(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) + * @method static \Illuminate\Http\Client\PendingRequest|mixed unless(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) * * @see \Illuminate\Http\Client\Factory */ @@ -64,4 +93,58 @@ protected static function getFacadeAccessor() { return Factory::class; } + + /** + * Register a stub callable that will intercept requests and be able to return stub responses. + * + * @param \Closure|array $callback + * @return \Illuminate\Http\Client\Factory + */ + public static function fake($callback = null) + { + return tap(static::getFacadeRoot(), function ($fake) use ($callback) { + static::swap($fake->fake($callback)); + }); + } + + /** + * Register a response sequence for the given URL pattern. + * + * @param string $urlPattern + * @return \Illuminate\Http\Client\ResponseSequence + */ + public static function fakeSequence(string $urlPattern = '*') + { + $fake = tap(static::getFacadeRoot(), function ($fake) { + static::swap($fake); + }); + + return $fake->fakeSequence($urlPattern); + } + + /** + * Indicate that an exception should be thrown if any request is not faked. + * + * @return \Illuminate\Http\Client\Factory + */ + public static function preventStrayRequests() + { + return tap(static::getFacadeRoot(), function ($fake) { + static::swap($fake->preventStrayRequests()); + }); + } + + /** + * Stub the given URL using the given callback. + * + * @param string $url + * @param \Illuminate\Http\Client\Response|\GuzzleHttp\Promise\PromiseInterface|callable $callback + * @return \Illuminate\Http\Client\Factory + */ + public static function stubUrl($url, $callback) + { + return tap(static::getFacadeRoot(), function ($fake) use ($url, $callback) { + static::swap($fake->stubUrl($url, $callback)); + }); + } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Lang.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Lang.php index 3e7ece4d2..992282cb2 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Lang.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Lang.php @@ -3,12 +3,32 @@ namespace Illuminate\Support\Facades; /** - * @method static bool hasForLocale(string $key, string $locale = null) - * @method static bool has(string $key, string $locale = null, bool $fallback = true) - * @method static mixed get(string $key, array $replace = [], string $locale = null, bool $fallback = true) - * @method static string choice(string $key, \Countable|int|array $number, array $replace = [], string $locale = null) + * @method static bool hasForLocale(string $key, string|null $locale = null) + * @method static bool has(string $key, string|null $locale = null, bool $fallback = true) + * @method static string|array get(string $key, array $replace = [], string|null $locale = null, bool $fallback = true) + * @method static string choice(string $key, \Countable|int|array $number, array $replace = [], string|null $locale = null) + * @method static void addLines(array $lines, string $locale, string $namespace = '*') + * @method static void load(string $namespace, string $group, string $locale) + * @method static void addNamespace(string $namespace, string $hint) + * @method static void addJsonPath(string $path) + * @method static array parseKey(string $key) + * @method static void determineLocalesUsing(callable $callback) + * @method static \Illuminate\Translation\MessageSelector getSelector() + * @method static void setSelector(\Illuminate\Translation\MessageSelector $selector) + * @method static \Illuminate\Contracts\Translation\Loader getLoader() + * @method static string locale() * @method static string getLocale() * @method static void setLocale(string $locale) + * @method static string getFallback() + * @method static void setFallback(string $fallback) + * @method static void setLoaded(array $loaded) + * @method static void stringable(callable|string $class, callable|null $handler = null) + * @method static void setParsedKey(string $key, array $parsed) + * @method static void flushParsedKeys() + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Translation\Translator */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Log.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Log.php index 68493fd22..48cd34086 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Log.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Log.php @@ -3,24 +3,36 @@ namespace Illuminate\Support\Facades; /** - * @method static \Psr\Log\LoggerInterface channel(string $channel = null) - * @method static \Psr\Log\LoggerInterface stack(array $channels, string $channel = null) * @method static \Psr\Log\LoggerInterface build(array $config) - * @method static \Illuminate\Log\Logger withContext(array $context = []) - * @method static \Illuminate\Log\Logger withoutContext() + * @method static \Psr\Log\LoggerInterface stack(array $channels, string|null $channel = null) + * @method static \Psr\Log\LoggerInterface channel(string|null $channel = null) + * @method static \Psr\Log\LoggerInterface driver(string|null $driver = null) + * @method static \Illuminate\Log\LogManager shareContext(array $context) + * @method static array sharedContext() + * @method static \Illuminate\Log\LogManager flushSharedContext() + * @method static string|null getDefaultDriver() + * @method static void setDefaultDriver(string $name) + * @method static \Illuminate\Log\LogManager extend(string $driver, \Closure $callback) + * @method static void forgetChannel(string|null $driver = null) + * @method static array getChannels() + * @method static void emergency(string $message, array $context = []) * @method static void alert(string $message, array $context = []) * @method static void critical(string $message, array $context = []) - * @method static void debug(string $message, array $context = []) - * @method static void emergency(string $message, array $context = []) * @method static void error(string $message, array $context = []) - * @method static void info(string $message, array $context = []) - * @method static void log($level, string $message, array $context = []) - * @method static void notice(string $message, array $context = []) * @method static void warning(string $message, array $context = []) - * @method static void write(string $level, string $message, array $context = []) + * @method static void notice(string $message, array $context = []) + * @method static void info(string $message, array $context = []) + * @method static void debug(string $message, array $context = []) + * @method static void log(mixed $level, string $message, array $context = []) + * @method static void write(string $level, \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message, array $context = []) + * @method static \Illuminate\Log\Logger withContext(array $context = []) + * @method static \Illuminate\Log\Logger withoutContext() * @method static void listen(\Closure $callback) + * @method static \Psr\Log\LoggerInterface getLogger() + * @method static \Illuminate\Contracts\Events\Dispatcher getEventDispatcher() + * @method static void setEventDispatcher(\Illuminate\Contracts\Events\Dispatcher $dispatcher) * - * @see \Illuminate\Log\Logger + * @see \Illuminate\Log\LogManager */ class Log extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Mail.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Mail.php index 103884c47..a6544a3a8 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Mail.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Mail.php @@ -5,34 +5,56 @@ use Illuminate\Support\Testing\Fakes\MailFake; /** - * @method static \Illuminate\Mail\Mailer mailer(string|null $name = null) + * @method static \Illuminate\Contracts\Mail\Mailer mailer(string|null $name = null) + * @method static \Illuminate\Mail\Mailer driver(string|null $driver = null) + * @method static \Symfony\Component\Mailer\Transport\TransportInterface createSymfonyTransport(array $config) + * @method static string getDefaultDriver() + * @method static void setDefaultDriver(string $name) + * @method static void purge(string|null $name = null) + * @method static \Illuminate\Mail\MailManager extend(string $driver, \Closure $callback) + * @method static \Illuminate\Contracts\Foundation\Application getApplication() + * @method static \Illuminate\Mail\MailManager setApplication(\Illuminate\Contracts\Foundation\Application $app) + * @method static \Illuminate\Mail\MailManager forgetMailers() * @method static void alwaysFrom(string $address, string|null $name = null) * @method static void alwaysReplyTo(string $address, string|null $name = null) * @method static void alwaysReturnPath(string $address) * @method static void alwaysTo(string $address, string|null $name = null) - * @method static \Illuminate\Mail\PendingMail bcc($users) - * @method static \Illuminate\Mail\PendingMail to($users) - * @method static \Illuminate\Support\Collection queued(string $mailable, \Closure|string $callback = null) - * @method static \Illuminate\Support\Collection sent(string $mailable, \Closure|string $callback = null) - * @method static array failures() - * @method static bool hasQueued(string $mailable) - * @method static bool hasSent(string $mailable) - * @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, \Illuminate\Contracts\Mail\Mailable|string|array $view, string $queue = null) - * @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, \Illuminate\Contracts\Mail\Mailable|string|array $view) - * @method static mixed queue(\Illuminate\Contracts\Mail\Mailable|string|array $view, string $queue = null) - * @method static mixed queueOn(string $queue, \Illuminate\Contracts\Mail\Mailable|string|array $view) - * @method static void assertNotQueued(string $mailable, callable $callback = null) - * @method static void assertNotSent(string $mailable, callable|int $callback = null) - * @method static void assertNothingQueued() + * @method static \Illuminate\Mail\PendingMail to(mixed $users) + * @method static \Illuminate\Mail\PendingMail cc(mixed $users) + * @method static \Illuminate\Mail\PendingMail bcc(mixed $users) + * @method static \Illuminate\Mail\SentMessage|null html(string $html, mixed $callback) + * @method static \Illuminate\Mail\SentMessage|null raw(string $text, mixed $callback) + * @method static \Illuminate\Mail\SentMessage|null plain(string $view, array $data, mixed $callback) + * @method static string render(string|array $view, array $data = []) + * @method static \Illuminate\Mail\SentMessage|null send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string|null $callback = null) + * @method static mixed queue(\Illuminate\Contracts\Mail\Mailable|string|array $view, string|null $queue = null) + * @method static mixed onQueue(string $queue, \Illuminate\Contracts\Mail\Mailable $view) + * @method static mixed queueOn(string $queue, \Illuminate\Contracts\Mail\Mailable $view) + * @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, \Illuminate\Contracts\Mail\Mailable $view, string|null $queue = null) + * @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, \Illuminate\Contracts\Mail\Mailable $view) + * @method static \Symfony\Component\Mailer\Transport\TransportInterface getSymfonyTransport() + * @method static \Illuminate\Contracts\View\Factory getViewFactory() + * @method static void setSymfonyTransport(\Symfony\Component\Mailer\Transport\TransportInterface $transport) + * @method static \Illuminate\Mail\Mailer setQueue(\Illuminate\Contracts\Queue\Factory $queue) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static void assertSent(string|\Closure $mailable, callable|int|null $callback = null) + * @method static void assertNotOutgoing(string|\Closure $mailable, callable|null $callback = null) + * @method static void assertNotSent(string|\Closure $mailable, callable|null $callback = null) + * @method static void assertNothingOutgoing() * @method static void assertNothingSent() - * @method static void assertQueued(string|\Closure $mailable, callable|int $callback = null) - * @method static void assertSent(string|\Closure $mailable, callable|int $callback = null) - * @method static void raw(string $text, $callback) - * @method static void plain(string $view, array $data, $callback) - * @method static void html(string $html, $callback) - * @method static void send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string $callback = null) + * @method static void assertQueued(string|\Closure $mailable, callable|int|null $callback = null) + * @method static void assertNotQueued(string|\Closure $mailable, callable|null $callback = null) + * @method static void assertNothingQueued() + * @method static \Illuminate\Support\Collection sent(string|\Closure $mailable, callable|null $callback = null) + * @method static bool hasSent(string $mailable) + * @method static \Illuminate\Support\Collection queued(string|\Closure $mailable, callable|null $callback = null) + * @method static bool hasQueued(string $mailable) + * @method static array failures() * - * @see \Illuminate\Mail\Mailer + * @see \Illuminate\Mail\MailManager * @see \Illuminate\Support\Testing\Fakes\MailFake */ class Mail extends Facade diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Notification.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Notification.php index e16a9ccea..74d56470b 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Notification.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Notification.php @@ -7,21 +7,38 @@ use Illuminate\Support\Testing\Fakes\NotificationFake; /** - * @method static \Illuminate\Notifications\ChannelManager locale(string|null $locale) - * @method static \Illuminate\Support\Collection sent(mixed $notifiable, string $notification, callable $callback = null) - * @method static bool hasSent(mixed $notifiable, string $notification) + * @method static void send(\Illuminate\Support\Collection|array|mixed $notifiables, mixed $notification) + * @method static void sendNow(\Illuminate\Support\Collection|array|mixed $notifiables, mixed $notification, array|null $channels = null) * @method static mixed channel(string|null $name = null) - * @method static void assertNotSentTo(mixed $notifiable, string|\Closure $notification, callable $callback = null) - * @method static void assertNothingSent() - * @method static void assertSentOnDemand(string|\Closure $notification, callable $callback = null) - * @method static void assertSentTo(mixed $notifiable, string|\Closure $notification, callable $callback = null) + * @method static string getDefaultDriver() + * @method static string deliversVia() + * @method static void deliverVia(string $channel) + * @method static \Illuminate\Notifications\ChannelManager locale(string $locale) + * @method static mixed driver(string|null $driver = null) + * @method static \Illuminate\Notifications\ChannelManager extend(string $driver, \Closure $callback) + * @method static array getDrivers() + * @method static \Illuminate\Contracts\Container\Container getContainer() + * @method static \Illuminate\Notifications\ChannelManager setContainer(\Illuminate\Contracts\Container\Container $container) + * @method static \Illuminate\Notifications\ChannelManager forgetDrivers() + * @method static void assertSentOnDemand(string|\Closure $notification, callable|null $callback = null) + * @method static void assertSentTo(mixed $notifiable, string|\Closure $notification, callable|null $callback = null) * @method static void assertSentOnDemandTimes(string $notification, int $times = 1) * @method static void assertSentToTimes(mixed $notifiable, string $notification, int $times = 1) - * @method static void assertTimesSent(int $expectedCount, string $notification) - * @method static void send(\Illuminate\Support\Collection|array|mixed $notifiables, $notification) - * @method static void sendNow(\Illuminate\Support\Collection|array|mixed $notifiables, $notification) + * @method static void assertNotSentTo(mixed $notifiable, string|\Closure $notification, callable|null $callback = null) + * @method static void assertNothingSent() + * @method static void assertNothingSentTo(mixed $notifiable) + * @method static void assertSentTimes(string $notification, int $expectedCount) + * @method static void assertCount(int $expectedCount) + * @method static \Illuminate\Support\Collection sent(mixed $notifiable, string $notification, callable|null $callback = null) + * @method static bool hasSent(mixed $notifiable, string $notification) + * @method static array sentNotifications() + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Notifications\ChannelManager + * @see \Illuminate\Support\Testing\Fakes\NotificationFake */ class Notification extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/ParallelTesting.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/ParallelTesting.php index c39761135..d91558c1c 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/ParallelTesting.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/ParallelTesting.php @@ -3,12 +3,20 @@ namespace Illuminate\Support\Facades; /** + * @method static void resolveOptionsUsing(\Closure|null $resolver) + * @method static void resolveTokenUsing(\Closure|null $resolver) * @method static void setUpProcess(callable $callback) * @method static void setUpTestCase(callable $callback) * @method static void setUpTestDatabase(callable $callback) * @method static void tearDownProcess(callable $callback) * @method static void tearDownTestCase(callable $callback) - * @method static int|false token() + * @method static void callSetUpProcessCallbacks() + * @method static void callSetUpTestCaseCallbacks(\Illuminate\Foundation\Testing\TestCase $testCase) + * @method static void callSetUpTestDatabaseCallbacks(string $database) + * @method static void callTearDownProcessCallbacks() + * @method static void callTearDownTestCaseCallbacks(\Illuminate\Foundation\Testing\TestCase $testCase) + * @method static mixed option(string $option) + * @method static string|false token() * * @see \Illuminate\Testing\ParallelTesting */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Password.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Password.php index 4ff371f9c..87d9daf6f 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Password.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Password.php @@ -5,15 +5,18 @@ use Illuminate\Contracts\Auth\PasswordBroker; /** + * @method static \Illuminate\Contracts\Auth\PasswordBroker broker(string|null $name = null) + * @method static string getDefaultDriver() + * @method static void setDefaultDriver(string $name) + * @method static string sendResetLink(array $credentials, \Closure|null $callback = null) * @method static mixed reset(array $credentials, \Closure $callback) - * @method static string sendResetLink(array $credentials, \Closure $callback = null) - * @method static \Illuminate\Contracts\Auth\CanResetPassword getUser(array $credentials) + * @method static \Illuminate\Contracts\Auth\CanResetPassword|null getUser(array $credentials) * @method static string createToken(\Illuminate\Contracts\Auth\CanResetPassword $user) * @method static void deleteToken(\Illuminate\Contracts\Auth\CanResetPassword $user) * @method static bool tokenExists(\Illuminate\Contracts\Auth\CanResetPassword $user, string $token) * @method static \Illuminate\Auth\Passwords\TokenRepositoryInterface getRepository() - * @method static \Illuminate\Contracts\Auth\PasswordBroker broker(string|null $name = null) * + * @see \Illuminate\Auth\Passwords\PasswordBrokerManager * @see \Illuminate\Auth\Passwords\PasswordBroker */ class Password extends Facade diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Queue.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Queue.php index 5af1329e0..60fc5fe7b 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Queue.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Queue.php @@ -6,24 +6,51 @@ use Illuminate\Support\Testing\Fakes\QueueFake; /** - * @method static \Illuminate\Contracts\Queue\Job|null pop(string $queue = null) - * @method static \Illuminate\Contracts\Queue\Queue setConnectionName(string $name) - * @method static int size(string $queue = null) - * @method static mixed bulk(array $jobs, mixed $data = '', string $queue = null) - * @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '', string $queue = null) - * @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '') - * @method static mixed push(string|object $job, mixed $data = '', $queue = null) + * @method static void before(mixed $callback) + * @method static void after(mixed $callback) + * @method static void exceptionOccurred(mixed $callback) + * @method static void looping(mixed $callback) + * @method static void failing(mixed $callback) + * @method static void stopping(mixed $callback) + * @method static bool connected(string|null $name = null) + * @method static \Illuminate\Contracts\Queue\Queue connection(string|null $name = null) + * @method static void extend(string $driver, \Closure $resolver) + * @method static void addConnector(string $driver, \Closure $resolver) + * @method static string getDefaultDriver() + * @method static void setDefaultDriver(string $name) + * @method static string getName(string|null $connection = null) + * @method static \Illuminate\Contracts\Foundation\Application getApplication() + * @method static \Illuminate\Queue\QueueManager setApplication(\Illuminate\Contracts\Foundation\Application $app) + * @method static int size(string|null $queue = null) + * @method static mixed push(string|object $job, mixed $data = '', string|null $queue = null) * @method static mixed pushOn(string $queue, string|object $job, mixed $data = '') - * @method static mixed pushRaw(string $payload, string $queue = null, array $options = []) + * @method static mixed pushRaw(string $payload, string|null $queue = null, array $options = []) + * @method static mixed later(\DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '', string|null $queue = null) + * @method static mixed laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, string|object $job, mixed $data = '') + * @method static mixed bulk(array $jobs, mixed $data = '', string|null $queue = null) + * @method static \Illuminate\Contracts\Queue\Job|null pop(string|null $queue = null) * @method static string getConnectionName() - * @method static void assertNotPushed(string|\Closure $job, callable $callback = null) + * @method static \Illuminate\Contracts\Queue\Queue setConnectionName(string $name) + * @method static mixed getJobBackoff(mixed $job) + * @method static mixed getJobExpiration(mixed $job) + * @method static void createPayloadUsing(callable|null $callback) + * @method static \Illuminate\Container\Container getContainer() + * @method static void setContainer(\Illuminate\Container\Container $container) + * @method static \Illuminate\Support\Testing\Fakes\QueueFake except(array|string $jobsToBeQueued) + * @method static void assertPushed(string|\Closure $job, callable|int|null $callback = null) + * @method static void assertPushedOn(string $queue, string|\Closure $job, callable|null $callback = null) + * @method static void assertPushedWithChain(string $job, array $expectedChain = [], callable|null $callback = null) + * @method static void assertPushedWithoutChain(string $job, callable|null $callback = null) + * @method static void assertNotPushed(string|\Closure $job, callable|null $callback = null) * @method static void assertNothingPushed() - * @method static void assertPushed(string|\Closure $job, callable|int $callback = null) - * @method static void assertPushedOn(string $queue, string|\Closure $job, callable $callback = null) - * @method static void assertPushedWithChain(string $job, array $expectedChain = [], callable $callback = null) + * @method static \Illuminate\Support\Collection pushed(string $job, callable|null $callback = null) + * @method static bool hasPushed(string $job) + * @method static bool shouldFakeJob(object $job) + * @method static array pushedJobs() * * @see \Illuminate\Queue\QueueManager * @see \Illuminate\Queue\Queue + * @see \Illuminate\Support\Testing\Fakes\QueueFake */ class Queue extends Facade { @@ -42,11 +69,12 @@ public static function popUsing($workerName, $callback) /** * Replace the bound instance with a fake. * + * @param array|string $jobsToFake * @return \Illuminate\Support\Testing\Fakes\QueueFake */ - public static function fake() + public static function fake($jobsToFake = []) { - static::swap($fake = new QueueFake(static::getFacadeApplication())); + static::swap($fake = new QueueFake(static::getFacadeApplication(), $jobsToFake, static::getFacadeRoot())); return $fake; } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/RateLimiter.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/RateLimiter.php index 5cfd78462..1a7f08290 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/RateLimiter.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/RateLimiter.php @@ -5,14 +5,16 @@ /** * @method static \Illuminate\Cache\RateLimiter for(string $name, \Closure $callback) * @method static \Closure limiter(string $name) - * @method static bool tooManyAttempts($key, $maxAttempts) - * @method static int hit($key, $decaySeconds = 60) - * @method static mixed attempts($key) - * @method static mixed resetAttempts($key) - * @method static int retriesLeft($key, $maxAttempts) - * @method static void clear($key) - * @method static int availableIn($key) - * @method static bool attempt($key, $maxAttempts, \Closure $callback, $decaySeconds = 60) + * @method static mixed attempt(string $key, int $maxAttempts, \Closure $callback, int $decaySeconds = 60) + * @method static bool tooManyAttempts(string $key, int $maxAttempts) + * @method static int hit(string $key, int $decaySeconds = 60) + * @method static mixed attempts(string $key) + * @method static mixed resetAttempts(string $key) + * @method static int remaining(string $key, int $maxAttempts) + * @method static int retriesLeft(string $key, int $maxAttempts) + * @method static void clear(string $key) + * @method static int availableIn(string $key) + * @method static string cleanRateLimiterKey(string $key) * * @see \Illuminate\Cache\RateLimiter */ @@ -25,6 +27,6 @@ class RateLimiter extends Facade */ protected static function getFacadeAccessor() { - return 'Illuminate\Cache\RateLimiter'; + return \Illuminate\Cache\RateLimiter::class; } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Redirect.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Redirect.php index c8569b394..ce96f7e8c 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Redirect.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Redirect.php @@ -3,21 +3,25 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Http\RedirectResponse action(string $action, mixed $parameters = [], int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse away(string $path, int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse back(int $status = 302, array $headers = [], $fallback = false) - * @method static \Illuminate\Http\RedirectResponse guest(string $path, int $status = 302, array $headers = [], bool $secure = null) - * @method static \Illuminate\Http\RedirectResponse home(int $status = 302) - * @method static \Illuminate\Http\RedirectResponse intended(string $default = '/', int $status = 302, array $headers = [], bool $secure = null) + * @method static \Illuminate\Http\RedirectResponse back(int $status = 302, array $headers = [], mixed $fallback = false) * @method static \Illuminate\Http\RedirectResponse refresh(int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse route(string $route, mixed $parameters = [], int $status = 302, array $headers = []) + * @method static \Illuminate\Http\RedirectResponse guest(string $path, int $status = 302, array $headers = [], bool|null $secure = null) + * @method static \Illuminate\Http\RedirectResponse intended(mixed $default = '/', int $status = 302, array $headers = [], bool|null $secure = null) + * @method static \Illuminate\Http\RedirectResponse to(string $path, int $status = 302, array $headers = [], bool|null $secure = null) + * @method static \Illuminate\Http\RedirectResponse away(string $path, int $status = 302, array $headers = []) * @method static \Illuminate\Http\RedirectResponse secure(string $path, int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse signedRoute(string $name, mixed $parameters = [], \DateTimeInterface|\DateInterval|int $expiration = null, int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse temporarySignedRoute(string $name, \DateTimeInterface|\DateInterval|int $expiration, mixed $parameters = [], int $status = 302, array $headers = []) - * @method static \Illuminate\Http\RedirectResponse to(string $path, int $status = 302, array $headers = [], bool $secure = null) + * @method static \Illuminate\Http\RedirectResponse route(string $route, mixed $parameters = [], int $status = 302, array $headers = []) + * @method static \Illuminate\Http\RedirectResponse signedRoute(string $route, mixed $parameters = [], \DateTimeInterface|\DateInterval|int|null $expiration = null, int $status = 302, array $headers = []) + * @method static \Illuminate\Http\RedirectResponse temporarySignedRoute(string $route, \DateTimeInterface|\DateInterval|int|null $expiration, mixed $parameters = [], int $status = 302, array $headers = []) + * @method static \Illuminate\Http\RedirectResponse action(string|array $action, mixed $parameters = [], int $status = 302, array $headers = []) * @method static \Illuminate\Routing\UrlGenerator getUrlGenerator() * @method static void setSession(\Illuminate\Session\Store $session) - * @method static void setIntendedUrl(string $url) + * @method static string|null getIntendedUrl() + * @method static \Illuminate\Routing\Redirector setIntendedUrl(string $url) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Routing\Redirector */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Redis.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Redis.php index 5073020cc..b796ad09d 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Redis.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Redis.php @@ -3,12 +3,34 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Redis\Connections\Connection connection(string $name = null) + * @method static \Illuminate\Redis\Connections\Connection connection(string|null $name = null) + * @method static \Illuminate\Redis\Connections\Connection resolve(string|null $name = null) + * @method static array connections() + * @method static void enableEvents() + * @method static void disableEvents() + * @method static void setDriver(string $driver) + * @method static void purge(string|null $name = null) + * @method static \Illuminate\Redis\RedisManager extend(string $driver, \Closure $callback) + * @method static void createSubscription(array|string $channels, \Closure $callback, string $method = 'subscribe') * @method static \Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder funnel(string $name) * @method static \Illuminate\Redis\Limiters\DurationLimiterBuilder throttle(string $name) + * @method static mixed client() + * @method static void subscribe(array|string $channels, \Closure $callback) + * @method static void psubscribe(array|string $channels, \Closure $callback) + * @method static mixed command(string $method, array $parameters = []) + * @method static void listen(\Closure $callback) + * @method static string|null getName() + * @method static \Illuminate\Redis\Connections\Connection setName(string $name) + * @method static \Illuminate\Contracts\Events\Dispatcher getEventDispatcher() + * @method static void setEventDispatcher(\Illuminate\Contracts\Events\Dispatcher $events) + * @method static void unsetEventDispatcher() + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static mixed macroCall(string $method, array $parameters) * * @see \Illuminate\Redis\RedisManager - * @see \Illuminate\Contracts\Redis\Factory */ class Redis extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Request.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Request.php index 05496d9cc..411663cbc 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Request.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Request.php @@ -3,89 +3,182 @@ namespace Illuminate\Support\Facades; /** - * @method static \Closure getRouteResolver() - * @method static \Closure getUserResolver() * @method static \Illuminate\Http\Request capture() - * @method static \Illuminate\Http\Request createFrom(\Illuminate\Http\Request $from, \Illuminate\Http\Request|null $to = null) - * @method static \Illuminate\Http\Request createFromBase(\Symfony\Component\HttpFoundation\Request $request) - * @method static \Illuminate\Http\Request duplicate(array|null $query = null, array|null $request = null, array|null $attributes = null, array|null $cookies = null, array|null $files = null, array|null $server = null) * @method static \Illuminate\Http\Request instance() + * @method static string method() + * @method static string root() + * @method static string url() + * @method static string fullUrl() + * @method static string fullUrlWithQuery(array $query) + * @method static string fullUrlWithoutQuery(array|string $keys) + * @method static string path() + * @method static string decodedPath() + * @method static string|null segment(int $index, string|null $default = null) + * @method static array segments() + * @method static bool is(mixed ...$patterns) + * @method static bool routeIs(mixed ...$patterns) + * @method static bool fullUrlIs(mixed ...$patterns) + * @method static string host() + * @method static string httpHost() + * @method static string schemeAndHttpHost() + * @method static bool ajax() + * @method static bool pjax() + * @method static bool prefetch() + * @method static bool secure() + * @method static string|null ip() + * @method static array ips() + * @method static string|null userAgent() * @method static \Illuminate\Http\Request merge(array $input) + * @method static \Illuminate\Http\Request mergeIfMissing(array $input) * @method static \Illuminate\Http\Request replace(array $input) + * @method static mixed get(string $key, mixed $default = null) + * @method static \Symfony\Component\HttpFoundation\ParameterBag|mixed json(string|null $key = null, mixed $default = null) + * @method static \Illuminate\Http\Request createFrom(\Illuminate\Http\Request $from, \Illuminate\Http\Request|null $to = null) + * @method static \Illuminate\Http\Request createFromBase(\Symfony\Component\HttpFoundation\Request $request) + * @method static \Illuminate\Http\Request duplicate(array|null $query = null, array|null $request = null, array|null $attributes = null, array|null $cookies = null, array|null $files = null, array|null $server = null) + * @method static bool hasSession(bool $skipIfUninitialized = false) + * @method static \Symfony\Component\HttpFoundation\Session\SessionInterface getSession() + * @method static \Illuminate\Contracts\Session\Session session() + * @method static void setLaravelSession(\Illuminate\Contracts\Session\Session $session) + * @method static void setRequestLocale(string $locale) + * @method static void setDefaultRequestLocale(string $locale) + * @method static mixed user(string|null $guard = null) + * @method static \Illuminate\Routing\Route|object|string|null route(string|null $param = null, mixed $default = null) + * @method static string fingerprint() * @method static \Illuminate\Http\Request setJson(\Symfony\Component\HttpFoundation\ParameterBag $json) - * @method static \Illuminate\Http\Request setRouteResolver(\Closure $callback) + * @method static \Closure getUserResolver() * @method static \Illuminate\Http\Request setUserResolver(\Closure $callback) - * @method static \Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|array|null file(string|null $key = null, mixed $default = null) - * @method static \Illuminate\Routing\Route|object|string route(string|null $param = null, string|null $default = null) - * @method static \Illuminate\Session\Store session() - * @method static \Illuminate\Session\Store|null getSession() - * @method static \Symfony\Component\HttpFoundation\ParameterBag|mixed json(string|null $key = null, mixed $default = null) - * @method static array all(array|mixed|null $keys = null) - * @method static array allFiles() - * @method static array except(array|mixed $keys) - * @method static array ips() - * @method static array keys() - * @method static array only(array|mixed $keys) - * @method static array segments() + * @method static \Closure getRouteResolver() + * @method static \Illuminate\Http\Request setRouteResolver(\Closure $callback) * @method static array toArray() - * @method static array validate(array $rules, ...$params) - * @method static array validateWithBag(string $errorBag, array $rules, ...$params) + * @method static void initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], string|resource|null $content = null) + * @method static \static createFromGlobals() + * @method static \static create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], string|resource|null $content = null) + * @method static void setFactory(callable|null $callable) + * @method static void overrideGlobals() + * @method static void setTrustedProxies(array $proxies, int $trustedHeaderSet) + * @method static string[] getTrustedProxies() + * @method static int getTrustedHeaderSet() + * @method static void setTrustedHosts(array $hostPatterns) + * @method static string[] getTrustedHosts() + * @method static string normalizeQueryString(string|null $qs) + * @method static void enableHttpMethodParameterOverride() + * @method static bool getHttpMethodParameterOverride() + * @method static bool hasPreviousSession() + * @method static void setSession(\Symfony\Component\HttpFoundation\Session\SessionInterface $session) + * @method static array getClientIps() + * @method static string|null getClientIp() + * @method static string getScriptName() + * @method static string getPathInfo() + * @method static string getBasePath() + * @method static string getBaseUrl() + * @method static string getScheme() + * @method static int|string|null getPort() + * @method static string|null getUser() + * @method static string|null getPassword() + * @method static string|null getUserInfo() + * @method static string getHttpHost() + * @method static string getRequestUri() + * @method static string getSchemeAndHttpHost() + * @method static string getUri() + * @method static string getUriForPath(string $path) + * @method static string getRelativeUriForPath(string $path) + * @method static string|null getQueryString() + * @method static bool isSecure() + * @method static string getHost() + * @method static void setMethod(string $method) + * @method static string getMethod() + * @method static string getRealMethod() + * @method static string|null getMimeType(string $format) + * @method static string[] getMimeTypes(string $format) + * @method static string|null getFormat(string|null $mimeType) + * @method static void setFormat(string|null $format, string|string[] $mimeTypes) + * @method static string|null getRequestFormat(string|null $default = 'html') + * @method static void setRequestFormat(string|null $format) + * @method static string|null getContentTypeFormat() + * @method static void setDefaultLocale(string $locale) + * @method static string getDefaultLocale() + * @method static void setLocale(string $locale) + * @method static string getLocale() + * @method static bool isMethod(string $method) + * @method static bool isMethodSafe() + * @method static bool isMethodIdempotent() + * @method static bool isMethodCacheable() + * @method static string|null getProtocolVersion() + * @method static string|resource getContent(bool $asResource = false) + * @method static \Symfony\Component\HttpFoundation\InputBag getPayload() + * @method static array getETags() + * @method static bool isNoCache() + * @method static string|null getPreferredFormat(string|null $default = 'html') + * @method static string|null getPreferredLanguage(string[] $locales = null) + * @method static string[] getLanguages() + * @method static string[] getCharsets() + * @method static string[] getEncodings() + * @method static string[] getAcceptableContentTypes() + * @method static bool isXmlHttpRequest() + * @method static bool preferSafeContent() + * @method static bool isFromTrustedProxy() + * @method static array filterPrecognitiveRules(array $rules) + * @method static bool isAttemptingPrecognition() + * @method static bool isPrecognitive() + * @method static bool isJson() + * @method static bool expectsJson() + * @method static bool wantsJson() * @method static bool accepts(string|array $contentTypes) + * @method static string|null prefers(string|array $contentTypes) * @method static bool acceptsAnyContentType() - * @method static bool acceptsHtml() * @method static bool acceptsJson() - * @method static bool ajax() - * @method static bool anyFilled(string|array $key) + * @method static bool acceptsHtml() + * @method static bool matchesType(string $actual, string $type) + * @method static string format(string $default = 'html') + * @method static string|array|null old(string|null $key = null, \Illuminate\Database\Eloquent\Model|string|array|null $default = null) + * @method static void flash() + * @method static void flashOnly(array|mixed $keys) + * @method static void flashExcept(array|mixed $keys) + * @method static void flush() + * @method static string|array|null server(string|null $key = null, string|array|null $default = null) + * @method static bool hasHeader(string $key) + * @method static string|array|null header(string|null $key = null, string|array|null $default = null) + * @method static string|null bearerToken() * @method static bool exists(string|array $key) - * @method static bool expectsJson() - * @method static bool filled(string|array $key) - * @method static bool fullUrlIs(mixed ...$patterns) * @method static bool has(string|array $key) - * @method static bool hasAny(string|array $key) + * @method static bool hasAny(string|array $keys) + * @method static \Illuminate\Http\Request|mixed whenHas(string $key, callable $callback, callable|null $default = null) + * @method static bool filled(string|array $key) + * @method static bool isNotFilled(string|array $key) + * @method static bool anyFilled(string|array $keys) + * @method static \Illuminate\Http\Request|mixed whenFilled(string $key, callable $callback, callable|null $default = null) + * @method static bool missing(string|array $key) + * @method static \Illuminate\Http\Request|mixed whenMissing(string $key, callable $callback, callable|null $default = null) + * @method static array keys() + * @method static array all(array|mixed|null $keys = null) + * @method static mixed input(string|null $key = null, mixed $default = null) + * @method static \Illuminate\Support\Stringable str(string $key, mixed $default = null) + * @method static \Illuminate\Support\Stringable string(string $key, mixed $default = null) + * @method static bool boolean(string|null $key = null, bool $default = false) + * @method static int integer(string $key, int $default = 0) + * @method static float float(string $key, float $default = 0) + * @method static \Illuminate\Support\Carbon|null date(string $key, string|null $format = null, string|null $tz = null) + * @method static object|null enum(string $key, string $enumClass) + * @method static \Illuminate\Support\Collection collect(array|string|null $key = null) + * @method static array only(array|mixed $keys) + * @method static array except(array|mixed $keys) + * @method static string|array|null query(string|null $key = null, string|array|null $default = null) + * @method static string|array|null post(string|null $key = null, string|array|null $default = null) * @method static bool hasCookie(string $key) + * @method static string|array|null cookie(string|null $key = null, string|array|null $default = null) + * @method static array allFiles() * @method static bool hasFile(string $key) - * @method static bool hasHeader(string $key) + * @method static \Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|array|null file(string|null $key = null, mixed $default = null) + * @method static never dd(mixed ...$keys) + * @method static \Illuminate\Http\Request dump(mixed $keys = []) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static array validate(array $rules, ...$params) + * @method static array validateWithBag(string $errorBag, array $rules, ...$params) * @method static bool hasValidSignature(bool $absolute = true) - * @method static bool is(mixed ...$patterns) - * @method static bool isJson() - * @method static bool matchesType(string $actual, string $type) - * @method static bool offsetExists(string $offset) - * @method static bool pjax() - * @method static bool prefers(string|array $contentTypes) - * @method static bool prefetch() - * @method static bool routeIs(mixed ...$patterns) - * @method static bool secure() - * @method static bool wantsJson() - * @method static mixed filterFiles(mixed $files) - * @method static mixed offsetGet(string $offset) - * @method static mixed user(string|null $guard = null) - * @method static string decodedPath() - * @method static string fingerprint() - * @method static string format($default = 'html') - * @method static string fullUrl() - * @method static string fullUrlWithQuery(array $query) - * @method static string method() - * @method static string path() - * @method static string root() - * @method static string url() - * @method static string userAgent() - * @method static string|array old(string|null $key = null, string|array|null $default = null) - * @method static string|array|null cookie(string|null $key = null, string|array|null $default = null) - * @method static string|array|null header(string|null $key = null, string|array|null $default = null) - * @method static string|array|null input(string|null $key = null, string|array|null $default = null) - * @method static string|array|null post(string|null $key = null, string|array|null $default = null) - * @method static string|array|null query(string|null $key = null, string|array|null $default = null) - * @method static string|array|null server(string|null $key = null, string|array|null $default = null) - * @method static string|null bearerToken() - * @method static string|null ip() - * @method static string|null segment(int $index, string|null $default = null) - * @method static void flash() - * @method static void flashExcept(array|mixed $keys) - * @method static void flashOnly(array|mixed $keys) - * @method static void flush() - * @method static void offsetSet(string $offset, mixed $value) - * @method static void offsetUnset(string $offset) - * @method static void setLaravelSession(\Illuminate\Contracts\Session\Session $session) * * @see \Illuminate\Http\Request */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Response.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Response.php index 6f319606e..6a9d46f2c 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Response.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Response.php @@ -5,22 +5,26 @@ use Illuminate\Contracts\Routing\ResponseFactory as ResponseFactoryContract; /** - * @method static \Illuminate\Http\JsonResponse json(string|array $data = [], int $status = 200, array $headers = [], int $options = 0) - * @method static \Illuminate\Http\JsonResponse jsonp(string $callback, string|array $data = [], int $status = 200, array $headers = [], int $options = 0) - * @method static \Illuminate\Http\RedirectResponse redirectGuest(string $path, int $status = 302, array $headers = [], bool|null $secure = null) + * @method static \Illuminate\Http\Response make(mixed $content = '', int $status = 200, array $headers = []) + * @method static \Illuminate\Http\Response noContent(int $status = 204, array $headers = []) + * @method static \Illuminate\Http\Response view(string|array $view, array $data = [], int $status = 200, array $headers = []) + * @method static \Illuminate\Http\JsonResponse json(mixed $data = [], int $status = 200, array $headers = [], int $options = 0) + * @method static \Illuminate\Http\JsonResponse jsonp(string $callback, mixed $data = [], int $status = 200, array $headers = [], int $options = 0) + * @method static \Symfony\Component\HttpFoundation\StreamedResponse stream(callable $callback, int $status = 200, array $headers = []) + * @method static \Symfony\Component\HttpFoundation\StreamedResponse streamDownload(callable $callback, string|null $name = null, array $headers = [], string|null $disposition = 'attachment') + * @method static \Symfony\Component\HttpFoundation\BinaryFileResponse download(\SplFileInfo|string $file, string|null $name = null, array $headers = [], string|null $disposition = 'attachment') + * @method static \Symfony\Component\HttpFoundation\BinaryFileResponse file(\SplFileInfo|string $file, array $headers = []) * @method static \Illuminate\Http\RedirectResponse redirectTo(string $path, int $status = 302, array $headers = [], bool|null $secure = null) + * @method static \Illuminate\Http\RedirectResponse redirectToRoute(string $route, mixed $parameters = [], int $status = 302, array $headers = []) * @method static \Illuminate\Http\RedirectResponse redirectToAction(string $action, mixed $parameters = [], int $status = 302, array $headers = []) + * @method static \Illuminate\Http\RedirectResponse redirectGuest(string $path, int $status = 302, array $headers = [], bool|null $secure = null) * @method static \Illuminate\Http\RedirectResponse redirectToIntended(string $default = '/', int $status = 302, array $headers = [], bool|null $secure = null) - * @method static \Illuminate\Http\RedirectResponse redirectToRoute(string $route, mixed $parameters = [], int $status = 302, array $headers = []) - * @method static \Illuminate\Http\Response make(array|string $content = '', int $status = 200, array $headers = []) - * @method static \Illuminate\Http\Response noContent($status = 204, array $headers = []) - * @method static \Illuminate\Http\Response view(string $view, array $data = [], int $status = 200, array $headers = []) - * @method static \Symfony\Component\HttpFoundation\BinaryFileResponse download(\SplFileInfo|string $file, string|null $name = null, array $headers = [], string|null $disposition = 'attachment') - * @method static \Symfony\Component\HttpFoundation\BinaryFileResponse file($file, array $headers = []) - * @method static \Symfony\Component\HttpFoundation\StreamedResponse stream(\Closure $callback, int $status = 200, array $headers = []) - * @method static \Symfony\Component\HttpFoundation\StreamedResponse streamDownload(\Closure $callback, string|null $name = null, array $headers = [], string|null $disposition = 'attachment') + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * - * @see \Illuminate\Contracts\Routing\ResponseFactory + * @see \Illuminate\Routing\ResponseFactory */ class Response extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Route.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Route.php index 4a97cdd19..6fdaf6ee1 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Route.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Route.php @@ -3,24 +3,89 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Routing\PendingResourceRegistration apiResource(string $name, string $controller, array $options = []) - * @method static \Illuminate\Routing\PendingResourceRegistration resource(string $name, string $controller, array $options = []) - * @method static \Illuminate\Routing\Route any(string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route|null current() - * @method static \Illuminate\Routing\Route delete(string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route fallback(array|string|callable|null $action = null) * @method static \Illuminate\Routing\Route get(string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route|null getCurrentRoute() - * @method static \Illuminate\Routing\RouteCollectionInterface getRoutes() - * @method static \Illuminate\Routing\Route match(array|string $methods, string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route options(string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route patch(string $uri, array|string|callable|null $action = null) - * @method static \Illuminate\Routing\Route permanentRedirect(string $uri, string $destination) * @method static \Illuminate\Routing\Route post(string $uri, array|string|callable|null $action = null) * @method static \Illuminate\Routing\Route put(string $uri, array|string|callable|null $action = null) + * @method static \Illuminate\Routing\Route patch(string $uri, array|string|callable|null $action = null) + * @method static \Illuminate\Routing\Route delete(string $uri, array|string|callable|null $action = null) + * @method static \Illuminate\Routing\Route options(string $uri, array|string|callable|null $action = null) + * @method static \Illuminate\Routing\Route any(string $uri, array|string|callable|null $action = null) + * @method static \Illuminate\Routing\Route fallback(array|string|callable|null $action) * @method static \Illuminate\Routing\Route redirect(string $uri, string $destination, int $status = 302) - * @method static \Illuminate\Routing\Route substituteBindings(\Illuminate\Support\Facades\Route $route) + * @method static \Illuminate\Routing\Route permanentRedirect(string $uri, string $destination) * @method static \Illuminate\Routing\Route view(string $uri, string $view, array $data = [], int|array $status = 200, array $headers = []) + * @method static \Illuminate\Routing\Route match(array|string $methods, string $uri, array|string|callable|null $action = null) + * @method static void resources(array $resources, array $options = []) + * @method static \Illuminate\Routing\PendingResourceRegistration resource(string $name, string $controller, array $options = []) + * @method static void apiResources(array $resources, array $options = []) + * @method static \Illuminate\Routing\PendingResourceRegistration apiResource(string $name, string $controller, array $options = []) + * @method static void singletons(array $singletons, array $options = []) + * @method static \Illuminate\Routing\PendingSingletonResourceRegistration singleton(string $name, string $controller, array $options = []) + * @method static void apiSingletons(array $singletons, array $options = []) + * @method static \Illuminate\Routing\PendingSingletonResourceRegistration apiSingleton(string $name, string $controller, array $options = []) + * @method static \Illuminate\Routing\Router group(array $attributes, \Closure|array|string $routes) + * @method static array mergeWithLastGroup(array $new, bool $prependExistingPrefix = true) + * @method static string getLastGroupPrefix() + * @method static \Illuminate\Routing\Route addRoute(array|string $methods, string $uri, array|string|callable|null $action) + * @method static \Illuminate\Routing\Route newRoute(array|string $methods, string $uri, mixed $action) + * @method static \Symfony\Component\HttpFoundation\Response respondWithRoute(string $name) + * @method static \Symfony\Component\HttpFoundation\Response dispatch(\Illuminate\Http\Request $request) + * @method static \Symfony\Component\HttpFoundation\Response dispatchToRoute(\Illuminate\Http\Request $request) + * @method static array gatherRouteMiddleware(\Illuminate\Routing\Route $route) + * @method static array resolveMiddleware(array $middleware, array $excluded = []) + * @method static \Symfony\Component\HttpFoundation\Response prepareResponse(\Symfony\Component\HttpFoundation\Request $request, mixed $response) + * @method static \Symfony\Component\HttpFoundation\Response toResponse(\Symfony\Component\HttpFoundation\Request $request, mixed $response) + * @method static \Illuminate\Routing\Route substituteBindings(\Illuminate\Routing\Route $route) + * @method static void substituteImplicitBindings(\Illuminate\Routing\Route $route) + * @method static void matched(string|callable $callback) + * @method static array getMiddleware() + * @method static \Illuminate\Routing\Router aliasMiddleware(string $name, string $class) + * @method static bool hasMiddlewareGroup(string $name) + * @method static array getMiddlewareGroups() + * @method static \Illuminate\Routing\Router middlewareGroup(string $name, array $middleware) + * @method static \Illuminate\Routing\Router prependMiddlewareToGroup(string $group, string $middleware) + * @method static \Illuminate\Routing\Router pushMiddlewareToGroup(string $group, string $middleware) + * @method static \Illuminate\Routing\Router removeMiddlewareFromGroup(string $group, string $middleware) + * @method static \Illuminate\Routing\Router flushMiddlewareGroups() + * @method static void bind(string $key, string|callable $binder) + * @method static void model(string $key, string $class, \Closure|null $callback = null) + * @method static \Closure|null getBindingCallback(string $key) + * @method static array getPatterns() + * @method static void pattern(string $key, string $pattern) + * @method static void patterns(array $patterns) + * @method static bool hasGroupStack() + * @method static array getGroupStack() + * @method static mixed input(string $key, string|null $default = null) + * @method static \Illuminate\Http\Request getCurrentRequest() + * @method static \Illuminate\Routing\Route|null getCurrentRoute() + * @method static \Illuminate\Routing\Route|null current() + * @method static bool has(string|array $name) + * @method static string|null currentRouteName() + * @method static bool is(mixed ...$patterns) + * @method static bool currentRouteNamed(mixed ...$patterns) + * @method static string|null currentRouteAction() + * @method static bool uses(array ...$patterns) + * @method static bool currentRouteUses(string $action) + * @method static void singularResourceParameters(bool $singular = true) + * @method static void resourceParameters(array $parameters = []) + * @method static array|null resourceVerbs(array $verbs = []) + * @method static \Illuminate\Routing\RouteCollectionInterface getRoutes() + * @method static void setRoutes(\Illuminate\Routing\RouteCollection $routes) + * @method static void setCompiledRoutes(array $routes) + * @method static array uniqueMiddleware(array $middleware) + * @method static \Illuminate\Routing\Router setContainer(\Illuminate\Container\Container $container) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static mixed macroCall(string $method, array $parameters) + * @method static \Illuminate\Routing\RouteRegistrar attribute(string $key, mixed $value) + * @method static \Illuminate\Routing\RouteRegistrar whereAlpha(array|string $parameters) + * @method static \Illuminate\Routing\RouteRegistrar whereAlphaNumeric(array|string $parameters) + * @method static \Illuminate\Routing\RouteRegistrar whereNumber(array|string $parameters) + * @method static \Illuminate\Routing\RouteRegistrar whereUlid(array|string $parameters) + * @method static \Illuminate\Routing\RouteRegistrar whereUuid(array|string $parameters) + * @method static \Illuminate\Routing\RouteRegistrar whereIn(array|string $parameters, array $values) * @method static \Illuminate\Routing\RouteRegistrar as(string $value) * @method static \Illuminate\Routing\RouteRegistrar controller(string $controller) * @method static \Illuminate\Routing\RouteRegistrar domain(string $value) @@ -31,20 +96,7 @@ * @method static \Illuminate\Routing\RouteRegistrar scopeBindings() * @method static \Illuminate\Routing\RouteRegistrar where(array $where) * @method static \Illuminate\Routing\RouteRegistrar withoutMiddleware(array|string $middleware) - * @method static \Illuminate\Routing\Router|\Illuminate\Routing\RouteRegistrar group(\Closure|string|array $attributes, \Closure|string $routes) - * @method static \Illuminate\Routing\ResourceRegistrar resourceVerbs(array $verbs = []) - * @method static string|null currentRouteAction() - * @method static string|null currentRouteName() - * @method static void apiResources(array $resources, array $options = []) - * @method static void bind(string $key, string|callable $binder) - * @method static void model(string $key, string $class, \Closure|null $callback = null) - * @method static void pattern(string $key, string $pattern) - * @method static void resources(array $resources, array $options = []) - * @method static void substituteImplicitBindings(\Illuminate\Support\Facades\Route $route) - * @method static boolean uses(...$patterns) - * @method static boolean is(...$patterns) - * @method static boolean has(string $name) - * @method static mixed input(string $key, string|null $default = null) + * @method static \Illuminate\Routing\RouteRegistrar withoutScopedBindings() * * @see \Illuminate\Routing\Router */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Schema.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Schema.php index ffe59cb26..f3084d04d 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Schema.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Schema.php @@ -3,31 +3,48 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Database\Schema\Builder create(string $table, \Closure $callback) - * @method static \Illuminate\Database\Schema\Builder createDatabase(string $name) - * @method static \Illuminate\Database\Schema\Builder disableForeignKeyConstraints() - * @method static \Illuminate\Database\Schema\Builder drop(string $table) - * @method static \Illuminate\Database\Schema\Builder dropDatabaseIfExists(string $name) - * @method static \Illuminate\Database\Schema\Builder dropIfExists(string $table) - * @method static \Illuminate\Database\Schema\Builder enableForeignKeyConstraints() - * @method static \Illuminate\Database\Schema\Builder rename(string $from, string $to) - * @method static \Illuminate\Database\Schema\Builder table(string $table, \Closure $callback) + * @method static void defaultStringLength(int $length) + * @method static void defaultMorphKeyType(string $type) + * @method static void morphUsingUuids() + * @method static void morphUsingUlids() + * @method static void useNativeSchemaOperationsIfPossible(bool $value = true) + * @method static bool createDatabase(string $name) + * @method static bool dropDatabaseIfExists(string $name) + * @method static bool hasTable(string $table) * @method static bool hasColumn(string $table, string $column) * @method static bool hasColumns(string $table, array $columns) - * @method static bool dropColumns(string $table, array $columns) - * @method static bool hasTable(string $table) - * @method static void defaultStringLength(int $length) - * @method static void registerCustomDoctrineType(string $class, string $name, string $type) - * @method static array getColumnListing(string $table) + * @method static void whenTableHasColumn(string $table, string $column, \Closure $callback) + * @method static void whenTableDoesntHaveColumn(string $table, string $column, \Closure $callback) * @method static string getColumnType(string $table, string $column) - * @method static void morphUsingUuids() + * @method static array getColumnListing(string $table) + * @method static void table(string $table, \Closure $callback) + * @method static void create(string $table, \Closure $callback) + * @method static void drop(string $table) + * @method static void dropIfExists(string $table) + * @method static void dropColumns(string $table, string|array $columns) + * @method static void dropAllTables() + * @method static void dropAllViews() + * @method static void dropAllTypes() + * @method static void getAllTables() + * @method static void rename(string $from, string $to) + * @method static bool enableForeignKeyConstraints() + * @method static bool disableForeignKeyConstraints() + * @method static mixed withoutForeignKeyConstraints(\Closure $callback) * @method static \Illuminate\Database\Connection getConnection() * @method static \Illuminate\Database\Schema\Builder setConnection(\Illuminate\Database\Connection $connection) + * @method static void blueprintResolver(\Closure $resolver) * * @see \Illuminate\Database\Schema\Builder */ class Schema extends Facade { + /** + * Indicates if the resolved facade should be cached. + * + * @var bool + */ + protected static $cached = false; + /** * Get a schema builder instance for a connection. * @@ -40,12 +57,12 @@ public static function connection($name) } /** - * Get a schema builder instance for the default connection. + * Get the registered name of the component. * - * @return \Illuminate\Database\Schema\Builder + * @return string */ protected static function getFacadeAccessor() { - return static::$app['db']->connection()->getSchemaBuilder(); + return 'db.schema'; } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Session.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Session.php index a07232169..e1ea7534b 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Session.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Session.php @@ -3,33 +3,68 @@ namespace Illuminate\Support\Facades; /** - * @method static \SessionHandlerInterface getHandler() + * @method static bool shouldBlock() + * @method static string|null blockDriver() + * @method static array getSessionConfig() + * @method static string getDefaultDriver() + * @method static void setDefaultDriver(string $name) + * @method static mixed driver(string|null $driver = null) + * @method static \Illuminate\Session\SessionManager extend(string $driver, \Closure $callback) + * @method static array getDrivers() + * @method static \Illuminate\Contracts\Container\Container getContainer() + * @method static \Illuminate\Session\SessionManager setContainer(\Illuminate\Contracts\Container\Container $container) + * @method static \Illuminate\Session\SessionManager forgetDrivers() + * @method static bool start() + * @method static void save() + * @method static void ageFlashData() * @method static array all() + * @method static array only(array $keys) * @method static bool exists(string|array $key) - * @method static bool handlerNeedsRequest() + * @method static bool missing(string|array $key) * @method static bool has(string|array $key) - * @method static bool isStarted() - * @method static bool migrate(bool $destroy = false) - * @method static bool save() - * @method static bool start() - * @method static mixed get(string $key, $default = null) - * @method static mixed flash(string $key, $value = true) - * @method static mixed pull(string $key, $default = null) + * @method static mixed get(string $key, mixed $default = null) + * @method static mixed pull(string $key, mixed $default = null) + * @method static bool hasOldInput(string|null $key = null) + * @method static mixed getOldInput(string|null $key = null, mixed $default = null) + * @method static void replace(array $attributes) + * @method static void put(string|array $key, mixed $value = null) + * @method static mixed remember(string $key, \Closure $callback) + * @method static void push(string $key, mixed $value) + * @method static mixed increment(string $key, int $amount = 1) + * @method static int decrement(string $key, int $amount = 1) + * @method static void flash(string $key, mixed $value = true) + * @method static void now(string $key, mixed $value) + * @method static void reflash() + * @method static void keep(array|mixed $keys = null) + * @method static void flashInput(array $value) * @method static mixed remove(string $key) - * @method static string getId() + * @method static void forget(string|array $keys) + * @method static void flush() + * @method static bool invalidate() + * @method static bool regenerate(bool $destroy = false) + * @method static bool migrate(bool $destroy = false) + * @method static bool isStarted() * @method static string getName() + * @method static void setName(string $name) + * @method static string getId() + * @method static void setId(string|null $id) + * @method static bool isValidId(string|null $id) + * @method static void setExists(bool $value) * @method static string token() + * @method static void regenerateToken() * @method static string|null previousUrl() - * @method static void flush() - * @method static void forget(string|array $keys) - * @method static void push(string $key, mixed $value) - * @method static void put(string|array $key, $value = null) - * @method static void setId(string $id) * @method static void setPreviousUrl(string $url) + * @method static void passwordConfirmed() + * @method static \SessionHandlerInterface getHandler() + * @method static \SessionHandlerInterface setHandler(\SessionHandlerInterface $handler) + * @method static bool handlerNeedsRequest() * @method static void setRequestOnHandler(\Illuminate\Http\Request $request) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Session\SessionManager - * @see \Illuminate\Session\Store */ class Session extends Facade { diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Storage.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Storage.php index 5a09125ee..f8fcddd21 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Storage.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Storage.php @@ -5,43 +5,79 @@ use Illuminate\Filesystem\Filesystem; /** - * @method static \Illuminate\Contracts\Filesystem\Filesystem assertExists(string|array $path) - * @method static \Illuminate\Contracts\Filesystem\Filesystem assertMissing(string|array $path) - * @method static \Illuminate\Contracts\Filesystem\Filesystem cloud() - * @method static \Illuminate\Contracts\Filesystem\Filesystem build(string|array $root) + * @method static \Illuminate\Contracts\Filesystem\Filesystem drive(string|null $name = null) * @method static \Illuminate\Contracts\Filesystem\Filesystem disk(string|null $name = null) + * @method static \Illuminate\Contracts\Filesystem\Filesystem cloud() + * @method static \Illuminate\Contracts\Filesystem\Filesystem build(string|array $config) + * @method static \Illuminate\Contracts\Filesystem\Filesystem createLocalDriver(array $config) + * @method static \Illuminate\Contracts\Filesystem\Filesystem createFtpDriver(array $config) + * @method static \Illuminate\Contracts\Filesystem\Filesystem createSftpDriver(array $config) + * @method static \Illuminate\Contracts\Filesystem\Cloud createS3Driver(array $config) + * @method static \Illuminate\Contracts\Filesystem\Filesystem createScopedDriver(array $config) + * @method static \Illuminate\Filesystem\FilesystemManager set(string $name, mixed $disk) + * @method static string getDefaultDriver() + * @method static string getDefaultCloudDriver() + * @method static \Illuminate\Filesystem\FilesystemManager forgetDisk(array|string $disk) + * @method static void purge(string|null $name = null) * @method static \Illuminate\Filesystem\FilesystemManager extend(string $driver, \Closure $callback) - * @method static \Symfony\Component\HttpFoundation\StreamedResponse download(string $path, string|null $name = null, array|null $headers = []) - * @method static \Symfony\Component\HttpFoundation\StreamedResponse response(string $path, string|null $name = null, array|null $headers = [], string|null $disposition = 'inline') - * @method static array allDirectories(string|null $directory = null) - * @method static array allFiles(string|null $directory = null) - * @method static array directories(string|null $directory = null, bool $recursive = false) - * @method static array files(string|null $directory = null, bool $recursive = false) + * @method static \Illuminate\Filesystem\FilesystemManager setApplication(\Illuminate\Contracts\Foundation\Application $app) + * @method static bool exists(string $path) + * @method static string|null get(string $path) + * @method static resource|null readStream(string $path) + * @method static bool put(string $path, string|resource $contents, mixed $options = []) + * @method static bool writeStream(string $path, resource $resource, array $options = []) + * @method static string getVisibility(string $path) + * @method static bool setVisibility(string $path, string $visibility) + * @method static bool prepend(string $path, string $data) * @method static bool append(string $path, string $data) - * @method static bool copy(string $from, string $to) * @method static bool delete(string|array $paths) - * @method static bool deleteDirectory(string $directory) - * @method static bool exists(string $path) - * @method static bool makeDirectory(string $path) - * @method static bool missing(string $path) + * @method static bool copy(string $from, string $to) * @method static bool move(string $from, string $to) - * @method static bool prepend(string $path, string $data) - * @method static bool put(string $path, \Psr\Http\Message\StreamInterface|\Illuminate\Http\File|\Illuminate\Http\UploadedFile|string|resource $contents, mixed $options = []) - * @method static bool setVisibility(string $path, string $visibility) - * @method static bool writeStream(string $path, resource $resource, array $options = []) - * @method static int lastModified(string $path) * @method static int size(string $path) - * @method static resource|null readStream(string $path) - * @method static string get(string $path) - * @method static string getVisibility(string $path) + * @method static int lastModified(string $path) + * @method static array files(string|null $directory = null, bool $recursive = false) + * @method static array allFiles(string|null $directory = null) + * @method static array directories(string|null $directory = null, bool $recursive = false) + * @method static array allDirectories(string|null $directory = null) + * @method static bool makeDirectory(string $path) + * @method static bool deleteDirectory(string $directory) + * @method static \Illuminate\Filesystem\FilesystemAdapter assertExists(string|array $path, string|null $content = null) + * @method static \Illuminate\Filesystem\FilesystemAdapter assertMissing(string|array $path) + * @method static \Illuminate\Filesystem\FilesystemAdapter assertDirectoryEmpty(string $path) + * @method static bool missing(string $path) + * @method static bool fileExists(string $path) + * @method static bool fileMissing(string $path) + * @method static bool directoryExists(string $path) + * @method static bool directoryMissing(string $path) * @method static string path(string $path) - * @method static string temporaryUrl(string $path, \DateTimeInterface $expiration, array $options = []) - * @method static string url(string $path) - * @method static string|false mimeType(string $path) + * @method static \Symfony\Component\HttpFoundation\StreamedResponse response(string $path, string|null $name = null, array $headers = [], string|null $disposition = 'inline') + * @method static \Symfony\Component\HttpFoundation\StreamedResponse download(string $path, string|null $name = null, array $headers = []) * @method static string|false putFile(string $path, \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file, mixed $options = []) * @method static string|false putFileAs(string $path, \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file, string $name, mixed $options = []) - * @method static void macro(string $name, object|callable $macro) + * @method static string|false checksum(string $path, array $options = []) + * @method static string|false mimeType(string $path) + * @method static string url(string $path) + * @method static bool providesTemporaryUrls() + * @method static string temporaryUrl(string $path, \DateTimeInterface $expiration, array $options = []) + * @method static array temporaryUploadUrl(string $path, \DateTimeInterface $expiration, array $options = []) + * @method static \League\Flysystem\FilesystemOperator getDriver() + * @method static \League\Flysystem\FilesystemAdapter getAdapter() + * @method static array getConfig() * @method static void buildTemporaryUrlsUsing(\Closure $callback) + * @method static \Illuminate\Filesystem\FilesystemAdapter|mixed when(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) + * @method static \Illuminate\Filesystem\FilesystemAdapter|mixed unless(\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static mixed macroCall(string $method, array $parameters) + * @method static bool has(string $location) + * @method static string read(string $location) + * @method static \League\Flysystem\DirectoryListing listContents(string $location, bool $deep = false) + * @method static int fileSize(string $path) + * @method static string visibility(string $path) + * @method static void write(string $location, string $contents, array $config = []) + * @method static void createDirectory(string $location, array $config = []) * * @see \Illuminate\Filesystem\FilesystemManager */ @@ -70,7 +106,9 @@ public static function fake($disk = null, array $config = []) 'root' => $root, ]))); - return $fake; + return tap($fake)->buildTemporaryUrlsUsing(function ($path, $expiration) { + return URL::to($path.'?expiration='.$expiration->getTimestamp()); + }); } /** diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/URL.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/URL.php index 7d9941d7c..8da96f482 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/URL.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/URL.php @@ -3,24 +3,48 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Contracts\Routing\UrlGenerator setRootControllerNamespace(string $rootNamespace) - * @method static bool hasValidSignature(\Illuminate\Http\Request $request, bool $absolute = true) - * @method static string action(string|array $action, $parameters = [], bool $absolute = true) - * @method static string asset(string $path, bool $secure = null) - * @method static string secureAsset(string $path) - * @method static string current() * @method static string full() - * @method static void macro(string $name, object|callable $macro) - * @method static void mixin(object $mixin, bool $replace = true) - * @method static string previous($fallback = false) - * @method static string route(string $name, $parameters = [], bool $absolute = true) + * @method static string current() + * @method static string previous(mixed $fallback = false) + * @method static string previousPath(mixed $fallback = false) + * @method static string to(string $path, mixed $extra = [], bool|null $secure = null) * @method static string secure(string $path, array $parameters = []) - * @method static string signedRoute(string $name, array $parameters = [], \DateTimeInterface|\DateInterval|int $expiration = null, bool $absolute = true) + * @method static string asset(string $path, bool|null $secure = null) + * @method static string secureAsset(string $path) + * @method static string assetFrom(string $root, string $path, bool|null $secure = null) + * @method static string formatScheme(bool|null $secure = null) + * @method static string signedRoute(string $name, mixed $parameters = [], \DateTimeInterface|\DateInterval|int|null $expiration = null, bool $absolute = true) * @method static string temporarySignedRoute(string $name, \DateTimeInterface|\DateInterval|int $expiration, array $parameters = [], bool $absolute = true) - * @method static string to(string $path, $extra = [], bool $secure = null) - * @method static void defaults(array $defaults) - * @method static void forceScheme(string $scheme) + * @method static bool hasValidSignature(\Illuminate\Http\Request $request, bool $absolute = true, array $ignoreQuery = []) + * @method static bool hasValidRelativeSignature(\Illuminate\Http\Request $request, array $ignoreQuery = []) + * @method static bool hasCorrectSignature(\Illuminate\Http\Request $request, bool $absolute = true, array $ignoreQuery = []) + * @method static bool signatureHasNotExpired(\Illuminate\Http\Request $request) + * @method static string route(string $name, mixed $parameters = [], bool $absolute = true) + * @method static string toRoute(\Illuminate\Routing\Route $route, mixed $parameters, bool $absolute) + * @method static string action(string|array $action, mixed $parameters = [], bool $absolute = true) + * @method static array formatParameters(mixed|array $parameters) + * @method static string formatRoot(string $scheme, string|null $root = null) + * @method static string format(string $root, string $path, \Illuminate\Routing\Route|null $route = null) * @method static bool isValidUrl(string $path) + * @method static void defaults(array $defaults) + * @method static array getDefaultParameters() + * @method static void forceScheme(string|null $scheme) + * @method static void forceRootUrl(string|null $root) + * @method static \Illuminate\Routing\UrlGenerator formatHostUsing(\Closure $callback) + * @method static \Illuminate\Routing\UrlGenerator formatPathUsing(\Closure $callback) + * @method static \Closure pathFormatter() + * @method static \Illuminate\Http\Request getRequest() + * @method static void setRequest(\Illuminate\Http\Request $request) + * @method static \Illuminate\Routing\UrlGenerator setRoutes(\Illuminate\Routing\RouteCollectionInterface $routes) + * @method static \Illuminate\Routing\UrlGenerator setSessionResolver(callable $sessionResolver) + * @method static \Illuminate\Routing\UrlGenerator setKeyResolver(callable $keyResolver) + * @method static \Illuminate\Routing\UrlGenerator withKeyResolver(callable $keyResolver) + * @method static string getRootControllerNamespace() + * @method static \Illuminate\Routing\UrlGenerator setRootControllerNamespace(string $rootNamespace) + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() * * @see \Illuminate\Routing\UrlGenerator */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Validator.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Validator.php index 1087f4e3a..4d7002b39 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/Validator.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Validator.php @@ -3,12 +3,20 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Contracts\Validation\Validator make(array $data, array $rules, array $messages = [], array $customAttributes = []) - * @method static void excludeUnvalidatedArrayKeys() - * @method static void extend(string $rule, \Closure|string $extension, string $message = null) - * @method static void extendImplicit(string $rule, \Closure|string $extension, string $message = null) - * @method static void replacer(string $rule, \Closure|string $replacer) + * @method static \Illuminate\Validation\Validator make(array $data, array $rules, array $messages = [], array $customAttributes = []) * @method static array validate(array $data, array $rules, array $messages = [], array $customAttributes = []) + * @method static void extend(string $rule, \Closure|string $extension, string|null $message = null) + * @method static void extendImplicit(string $rule, \Closure|string $extension, string|null $message = null) + * @method static void extendDependent(string $rule, \Closure|string $extension, string|null $message = null) + * @method static void replacer(string $rule, \Closure|string $replacer) + * @method static void includeUnvalidatedArrayKeys() + * @method static void excludeUnvalidatedArrayKeys() + * @method static void resolver(\Closure $resolver) + * @method static \Illuminate\Contracts\Translation\Translator getTranslator() + * @method static \Illuminate\Validation\PresenceVerifierInterface getPresenceVerifier() + * @method static void setPresenceVerifier(\Illuminate\Validation\PresenceVerifierInterface $presenceVerifier) + * @method static \Illuminate\Contracts\Container\Container|null getContainer() + * @method static \Illuminate\Validation\Factory setContainer(\Illuminate\Contracts\Container\Container $container) * * @see \Illuminate\Validation\Factory */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/View.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/View.php index 4988ee977..10eaa645d 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Facades/View.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/View.php @@ -3,16 +3,83 @@ namespace Illuminate\Support\Facades; /** - * @method static \Illuminate\Contracts\View\Factory addNamespace(string $namespace, string|array $hints) + * @method static \Illuminate\Contracts\View\View file(string $path, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) + * @method static \Illuminate\Contracts\View\View make(string $view, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) * @method static \Illuminate\Contracts\View\View first(array $views, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) - * @method static \Illuminate\Contracts\View\Factory replaceNamespace(string $namespace, string|array $hints) - * @method static \Illuminate\Contracts\View\Factory addExtension(string $extension, string $engine, \Closure|null $resolver = null) - * @method static \Illuminate\Contracts\View\View file(string $path, array $data = [], array $mergeData = []) - * @method static \Illuminate\Contracts\View\View make(string $view, array $data = [], array $mergeData = []) - * @method static array composer(array|string $views, \Closure|string $callback) - * @method static array creator(array|string $views, \Closure|string $callback) + * @method static string renderWhen(bool $condition, string $view, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) + * @method static string renderUnless(bool $condition, string $view, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) + * @method static string renderEach(string $view, array $data, string $iterator, string $empty = 'raw|') * @method static bool exists(string $view) - * @method static mixed share(array|string $key, $value = null) + * @method static \Illuminate\Contracts\View\Engine getEngineFromPath(string $path) + * @method static mixed share(array|string $key, mixed|null $value = null) + * @method static void incrementRender() + * @method static void decrementRender() + * @method static bool doneRendering() + * @method static bool hasRenderedOnce(string $id) + * @method static void markAsRenderedOnce(string $id) + * @method static void addLocation(string $location) + * @method static \Illuminate\View\Factory addNamespace(string $namespace, string|array $hints) + * @method static \Illuminate\View\Factory prependNamespace(string $namespace, string|array $hints) + * @method static \Illuminate\View\Factory replaceNamespace(string $namespace, string|array $hints) + * @method static void addExtension(string $extension, string $engine, \Closure|null $resolver = null) + * @method static void flushState() + * @method static void flushStateIfDoneRendering() + * @method static array getExtensions() + * @method static \Illuminate\View\Engines\EngineResolver getEngineResolver() + * @method static \Illuminate\View\ViewFinderInterface getFinder() + * @method static void setFinder(\Illuminate\View\ViewFinderInterface $finder) + * @method static void flushFinderCache() + * @method static \Illuminate\Contracts\Events\Dispatcher getDispatcher() + * @method static void setDispatcher(\Illuminate\Contracts\Events\Dispatcher $events) + * @method static \Illuminate\Contracts\Container\Container getContainer() + * @method static void setContainer(\Illuminate\Contracts\Container\Container $container) + * @method static mixed shared(string $key, mixed $default = null) + * @method static array getShared() + * @method static void macro(string $name, object|callable $macro) + * @method static void mixin(object $mixin, bool $replace = true) + * @method static bool hasMacro(string $name) + * @method static void flushMacros() + * @method static void startComponent(\Illuminate\Contracts\View\View|\Illuminate\Contracts\Support\Htmlable|\Closure|string $view, array $data = []) + * @method static void startComponentFirst(array $names, array $data = []) + * @method static string renderComponent() + * @method static mixed|null getConsumableComponentData(string $key, mixed $default = null) + * @method static void slot(string $name, string|null $content = null, array $attributes = []) + * @method static void endSlot() + * @method static array creator(array|string $views, \Closure|string $callback) + * @method static array composers(array $composers) + * @method static array composer(array|string $views, \Closure|string $callback) + * @method static void callComposer(\Illuminate\Contracts\View\View $view) + * @method static void callCreator(\Illuminate\Contracts\View\View $view) + * @method static void startFragment(string $fragment) + * @method static string stopFragment() + * @method static mixed getFragment(string $name, string|null $default = null) + * @method static array getFragments() + * @method static void flushFragments() + * @method static void startSection(string $section, string|null $content = null) + * @method static void inject(string $section, string $content) + * @method static string yieldSection() + * @method static string stopSection(bool $overwrite = false) + * @method static string appendSection() + * @method static string yieldContent(string $section, string $default = '') + * @method static string parentPlaceholder(string $section = '') + * @method static bool hasSection(string $name) + * @method static bool sectionMissing(string $name) + * @method static mixed getSection(string $name, string|null $default = null) + * @method static array getSections() + * @method static void flushSections() + * @method static void addLoop(\Countable|array $data) + * @method static void incrementLoopIndices() + * @method static void popLoop() + * @method static \stdClass|null getLastLoop() + * @method static array getLoopStack() + * @method static void startPush(string $section, string $content = '') + * @method static string stopPush() + * @method static void startPrepend(string $section, string $content = '') + * @method static string stopPrepend() + * @method static string yieldPushContent(string $section, string $default = '') + * @method static void flushStacks() + * @method static void startTranslation(array $replacements = []) + * @method static string renderTranslation() * * @see \Illuminate\View\Factory */ diff --git a/lam/lib/3rdParty/composer/illuminate/support/Facades/Vite.php b/lam/lib/3rdParty/composer/illuminate/support/Facades/Vite.php new file mode 100644 index 000000000..f7b4f02b6 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/support/Facades/Vite.php @@ -0,0 +1,41 @@ + + * @implements \ArrayAccess + */ class Fluent implements Arrayable, ArrayAccess, Jsonable, JsonSerializable { /** * All of the attributes set on the fluent instance. * - * @var array + * @var array */ protected $attributes = []; /** * Create a new fluent instance. * - * @param array|object $attributes + * @param iterable $attributes * @return void */ public function __construct($attributes = []) @@ -32,9 +39,11 @@ public function __construct($attributes = []) /** * Get an attribute from the fluent instance. * - * @param string $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -48,7 +57,7 @@ public function get($key, $default = null) /** * Get the attributes from the fluent instance. * - * @return array + * @return array */ public function getAttributes() { @@ -58,7 +67,7 @@ public function getAttributes() /** * Convert the fluent instance to an array. * - * @return array + * @return array */ public function toArray() { @@ -68,10 +77,9 @@ public function toArray() /** * Convert the object into something JSON serializable. * - * @return array + * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } @@ -90,11 +98,10 @@ public function toJson($options = 0) /** * Determine if the given offset exists. * - * @param string $offset + * @param TKey $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->attributes[$offset]); } @@ -102,11 +109,10 @@ public function offsetExists($offset) /** * Get the value for a given offset. * - * @param string $offset - * @return mixed + * @param TKey $offset + * @return TValue|null */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->get($offset); } @@ -114,12 +120,11 @@ public function offsetGet($offset) /** * Set the value at the given offset. * - * @param string $offset - * @param mixed $value + * @param TKey $offset + * @param TValue $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->attributes[$offset] = $value; } @@ -127,11 +132,10 @@ public function offsetSet($offset, $value) /** * Unset the value at the given offset. * - * @param string $offset + * @param TKey $offset * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->attributes[$offset]); } @@ -139,13 +143,13 @@ public function offsetUnset($offset) /** * Handle dynamic calls to the fluent instance to set attributes. * - * @param string $method - * @param array $parameters + * @param TKey $method + * @param array{0: ?TValue} $parameters * @return $this */ public function __call($method, $parameters) { - $this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true; + $this->attributes[$method] = count($parameters) > 0 ? reset($parameters) : true; return $this; } @@ -153,8 +157,8 @@ public function __call($method, $parameters) /** * Dynamically retrieve the value of an attribute. * - * @param string $key - * @return mixed + * @param TKey $key + * @return TValue|null */ public function __get($key) { @@ -164,8 +168,8 @@ public function __get($key) /** * Dynamically set the value of an attribute. * - * @param string $key - * @param mixed $value + * @param TKey $key + * @param TValue $value * @return void */ public function __set($key, $value) @@ -176,7 +180,7 @@ public function __set($key, $value) /** * Dynamically check if an attribute is set. * - * @param string $key + * @param TKey $key * @return bool */ public function __isset($key) @@ -187,7 +191,7 @@ public function __isset($key) /** * Dynamically unset an attribute. * - * @param string $key + * @param TKey $key * @return void */ public function __unset($key) diff --git a/lam/lib/3rdParty/composer/illuminate/support/Js.php b/lam/lib/3rdParty/composer/illuminate/support/Js.php index 6d6de3440..69e9a7626 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Js.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Js.php @@ -2,6 +2,7 @@ namespace Illuminate\Support; +use BackedEnum; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Contracts\Support\Jsonable; @@ -69,6 +70,10 @@ protected function convertDataToJavaScriptExpression($data, $flags = 0, $depth = return $data->toHtml(); } + if ($data instanceof BackedEnum) { + $data = $data->value; + } + $json = $this->jsonEncode($data, $flags, $depth); if (is_string($data)) { @@ -112,7 +117,7 @@ protected function jsonEncode($data, $flags = 0, $depth = 512) */ protected function convertJsonToJavaScriptExpression($json, $flags = 0) { - if ('[]' === $json || '{}' === $json) { + if ($json === '[]' || $json === '{}') { return $json; } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Lottery.php b/lam/lib/3rdParty/composer/illuminate/support/Lottery.php new file mode 100644 index 000000000..9bf3b47d0 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/support/Lottery.php @@ -0,0 +1,271 @@ + 1) { + throw new RuntimeException('Float must not be greater than 1.'); + } + + $this->chances = $chances; + + $this->outOf = $outOf; + } + + /** + * Create a new Lottery instance. + * + * @param int|float $chances + * @param int|null $outOf + * @return static + */ + public static function odds($chances, $outOf = null) + { + return new static($chances, $outOf); + } + + /** + * Set the winner callback. + * + * @param callable $callback + * @return $this + */ + public function winner($callback) + { + $this->winner = $callback; + + return $this; + } + + /** + * Set the loser callback. + * + * @param callable $callback + * @return $this + */ + public function loser($callback) + { + $this->loser = $callback; + + return $this; + } + + /** + * Run the lottery. + * + * @param mixed ...$args + * @return mixed + */ + public function __invoke(...$args) + { + return $this->runCallback(...$args); + } + + /** + * Run the lottery. + * + * @param null|int $times + * @return mixed + */ + public function choose($times = null) + { + if ($times === null) { + return $this->runCallback(); + } + + $results = []; + + for ($i = 0; $i < $times; $i++) { + $results[] = $this->runCallback(); + } + + return $results; + } + + /** + * Run the winner or loser callback, randomly. + * + * @param mixed ...$args + * @return callable + */ + protected function runCallback(...$args) + { + return $this->wins() + ? ($this->winner ?? fn () => true)(...$args) + : ($this->loser ?? fn () => false)(...$args); + } + + /** + * Determine if the lottery "wins" or "loses". + * + * @return bool + */ + protected function wins() + { + return static::resultFactory()($this->chances, $this->outOf); + } + + /** + * The factory that determines the lottery result. + * + * @return callable + */ + protected static function resultFactory() + { + return static::$resultFactory ?? fn ($chances, $outOf) => $outOf === null + ? random_int(0, PHP_INT_MAX) / PHP_INT_MAX <= $chances + : random_int(1, $outOf) <= $chances; + } + + /** + * Force the lottery to always result in a win. + * + * @param callable|null $callback + * @return void + */ + public static function alwaysWin($callback = null) + { + self::setResultFactory(fn () => true); + + if ($callback === null) { + return; + } + + $callback(); + + static::determineResultNormally(); + } + + /** + * Force the lottery to always result in a lose. + * + * @param callable|null $callback + * @return void + */ + public static function alwaysLose($callback = null) + { + self::setResultFactory(fn () => false); + + if ($callback === null) { + return; + } + + $callback(); + + static::determineResultNormally(); + } + + /** + * Set the sequence that will be used to determine lottery results. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function fix($sequence, $whenMissing = null) + { + return static::forceResultWithSequence($sequence, $whenMissing); + } + + /** + * Set the sequence that will be used to determine lottery results. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function forceResultWithSequence($sequence, $whenMissing = null) + { + $next = 0; + + $whenMissing ??= function ($chances, $outOf) use (&$next) { + $factoryCache = static::$resultFactory; + + static::$resultFactory = null; + + $result = static::resultFactory()($chances, $outOf); + + static::$resultFactory = $factoryCache; + + $next++; + + return $result; + }; + + static::setResultFactory(function ($chances, $outOf) use (&$next, $sequence, $whenMissing) { + if (array_key_exists($next, $sequence)) { + return $sequence[$next++]; + } + + return $whenMissing($chances, $outOf); + }); + } + + /** + * Indicate that the lottery results should be determined normally. + * + * @return void + */ + public static function determineResultNormally() + { + static::$resultFactory = null; + } + + /** + * Set the factory that should be used to determine the lottery results. + * + * @param callable $factory + * @return void + */ + public static function setResultFactory($factory) + { + self::$resultFactory = $factory; + } +} diff --git a/lam/lib/3rdParty/composer/illuminate/support/MessageBag.php b/lam/lib/3rdParty/composer/illuminate/support/MessageBag.php index e53d509d3..88ebfb08b 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/MessageBag.php +++ b/lam/lib/3rdParty/composer/illuminate/support/MessageBag.php @@ -139,7 +139,7 @@ public function has($key) /** * Determine if messages exist for any of the given keys. * - * @param array|string $keys + * @param array|string|null $keys * @return bool */ public function hasAny($keys = []) @@ -193,7 +193,7 @@ public function get($key, $format = null) ); } - if (Str::contains($key, '*')) { + if (str_contains($key, '*')) { return $this->getMessagesForWildcardKey($key, $format); } @@ -260,6 +260,10 @@ public function unique($format = null) */ protected function transform($messages, $format, $messageKey) { + if ($format == ':message') { + return (array) $messages; + } + return collect((array) $messages) ->map(function ($message) use ($format, $messageKey) { // We will simply spin through the given messages and transform each one @@ -368,8 +372,7 @@ public function any() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->messages, COUNT_RECURSIVE) - count($this->messages); } @@ -389,8 +392,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/MultipleInstanceManager.php b/lam/lib/3rdParty/composer/illuminate/support/MultipleInstanceManager.php index 97cee33af..8544bdf71 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/MultipleInstanceManager.php +++ b/lam/lib/3rdParty/composer/illuminate/support/MultipleInstanceManager.php @@ -139,7 +139,7 @@ protected function callCustomCreator(array $config) */ public function forgetInstance($name = null) { - $name = $name ?? $this->getDefaultInstance(); + $name ??= $this->getDefaultInstance(); foreach ((array) $name as $instanceName) { if (isset($this->instances[$instanceName])) { @@ -158,7 +158,7 @@ public function forgetInstance($name = null) */ public function purge($name = null) { - $name = $name ?? $this->getDefaultInstance(); + $name ??= $this->getDefaultInstance(); unset($this->instances[$name]); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/NamespacedItemResolver.php b/lam/lib/3rdParty/composer/illuminate/support/NamespacedItemResolver.php index a0d8508b2..a059c6daf 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/NamespacedItemResolver.php +++ b/lam/lib/3rdParty/composer/illuminate/support/NamespacedItemResolver.php @@ -29,7 +29,7 @@ public function parseKey($key) // If the key does not contain a double colon, it means the key is not in a // namespace, and is just a regular configuration item. Namespaces are a // tool for organizing configuration items for things such as modules. - if (strpos($key, '::') === false) { + if (! str_contains($key, '::')) { $segments = explode('.', $key); $parsed = $this->parseBasicSegments($segments); diff --git a/lam/lib/3rdParty/composer/illuminate/support/Optional.php b/lam/lib/3rdParty/composer/illuminate/support/Optional.php index 816190dd7..ba84a2ccf 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Optional.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Optional.php @@ -68,8 +68,7 @@ public function __isset($name) * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return Arr::accessible($this->value) && Arr::exists($this->value, $key); } @@ -80,8 +79,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return Arr::get($this->value, $key); } @@ -93,8 +91,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { if (Arr::accessible($this->value)) { $this->value[$key] = $value; @@ -107,8 +104,7 @@ public function offsetSet($key, $value) * @param string $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { if (Arr::accessible($this->value)) { unset($this->value[$key]); diff --git a/lam/lib/3rdParty/composer/illuminate/support/Pluralizer.php b/lam/lib/3rdParty/composer/illuminate/support/Pluralizer.php index 109a10816..0d909de1e 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/Pluralizer.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Pluralizer.php @@ -2,60 +2,34 @@ namespace Illuminate\Support; -use Doctrine\Inflector\Inflector; use Doctrine\Inflector\InflectorFactory; class Pluralizer { /** - * Uncountable word forms. + * The cached inflector instance. + * + * @var static + */ + protected static $inflector; + + /** + * The language that should be used by the inflector. + * + * @var string + */ + protected static $language = 'english'; + + /** + * Uncountable non-nouns word forms. + * + * Contains words supported by Doctrine/Inflector/Rules/English/Uninflected.php * * @var string[] */ public static $uncountable = [ - 'audio', - 'bison', - 'cattle', - 'chassis', - 'compensation', - 'coreopsis', - 'data', - 'deer', - 'education', - 'emoji', - 'equipment', - 'evidence', - 'feedback', - 'firmware', - 'fish', - 'furniture', - 'gold', - 'hardware', - 'information', - 'jedi', - 'kin', - 'knowledge', - 'love', - 'metadata', - 'money', - 'moose', - 'news', - 'nutrition', - 'offspring', - 'plankton', - 'pokemon', - 'police', - 'rain', 'recommended', 'related', - 'rice', - 'series', - 'sheep', - 'software', - 'species', - 'swine', - 'traffic', - 'wheat', ]; /** @@ -131,12 +105,23 @@ protected static function matchCase($value, $comparison) */ public static function inflector() { - static $inflector; - - if (is_null($inflector)) { - $inflector = InflectorFactory::createForLanguage('english')->build(); + if (is_null(static::$inflector)) { + static::$inflector = InflectorFactory::createForLanguage(static::$language)->build(); } - return $inflector; + return static::$inflector; + } + + /** + * Specify the language that should be used by the inflector. + * + * @param string $language + * @return void + */ + public static function useLanguage(string $language) + { + static::$language = $language; + + static::$inflector = null; } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/ProcessUtils.php b/lam/lib/3rdParty/composer/illuminate/support/ProcessUtils.php index 1caa9e168..165e75168 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/ProcessUtils.php +++ b/lam/lib/3rdParty/composer/illuminate/support/ProcessUtils.php @@ -22,7 +22,7 @@ public static function escapeArgument($argument) // @see https://bugs.php.net/bug.php?id=43784 // @see https://bugs.php.net/bug.php?id=49446 if ('\\' === DIRECTORY_SEPARATOR) { - if ('' === $argument) { + if ($argument === '') { return '""'; } @@ -30,14 +30,14 @@ public static function escapeArgument($argument) $quote = false; foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { - if ('"' === $part) { + if ($part === '"') { $escapedArgument .= '\\"'; } elseif (self::isSurroundedBy($part, '%')) { // Avoid environment variable expansion $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%'; } else { // escape trailing backslash - if ('\\' === substr($part, -1)) { + if (str_ends_with($part, '\\')) { $part .= '\\'; } $quote = true; @@ -64,6 +64,6 @@ public static function escapeArgument($argument) */ protected static function isSurroundedBy($arg, $char) { - return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; + return strlen($arg) > 2 && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Reflector.php b/lam/lib/3rdParty/composer/illuminate/support/Reflector.php index 841bad686..1390c9dac 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Reflector.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Reflector.php @@ -3,6 +3,7 @@ namespace Illuminate\Support; use ReflectionClass; +use ReflectionEnum; use ReflectionMethod; use ReflectionNamedType; use ReflectionUnionType; @@ -22,8 +23,7 @@ public static function isCallable($var, $syntaxOnly = false) return is_callable($var, $syntaxOnly); } - if ((! isset($var[0]) || ! isset($var[1])) || - ! is_string($var[1] ?? null)) { + if (! isset($var[0], $var[1]) || ! is_string($var[1] ?? null)) { return false; } @@ -139,4 +139,24 @@ public static function isParameterSubclassOf($parameter, $className) && (class_exists($paramClassName) || interface_exists($paramClassName)) && (new ReflectionClass($paramClassName))->isSubclassOf($className); } + + /** + * Determine if the parameter's type is a Backed Enum with a string backing type. + * + * @param \ReflectionParameter $parameter + * @return bool + */ + public static function isParameterBackedEnumWithStringBackingType($parameter) + { + $backedEnumClass = (string) $parameter->getType(); + + if (function_exists('enum_exists') && enum_exists($backedEnumClass)) { + $reflectionBackedEnum = new ReflectionEnum($backedEnumClass); + + return $reflectionBackedEnum->isBacked() + && $reflectionBackedEnum->getBackingType()->getName() == 'string'; + } + + return false; + } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Str.php b/lam/lib/3rdParty/composer/illuminate/support/Str.php index 21e190403..e103ccd8c 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Str.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Str.php @@ -2,12 +2,20 @@ namespace Illuminate\Support; +use Closure; use Illuminate\Support\Traits\Macroable; +use JsonException; +use League\CommonMark\Environment\Environment; +use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; +use League\CommonMark\Extension\InlinesOnly\InlinesOnlyExtension; use League\CommonMark\GithubFlavoredMarkdownConverter; +use League\CommonMark\MarkdownConverter; use Ramsey\Uuid\Codec\TimestampFirstCombCodec; use Ramsey\Uuid\Generator\CombGenerator; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidFactory; +use Symfony\Component\Uid\Ulid; +use Traversable; use voku\helper\ASCII; class Str @@ -38,10 +46,17 @@ class Str /** * The callback that should be used to generate UUIDs. * - * @var callable + * @var callable|null */ protected static $uuidFactory; + /** + * The callback that should be used to generate random strings. + * + * @var callable|null + */ + protected static $randomStringFactory; + /** * Get a new stringable object from the given string. * @@ -169,6 +184,23 @@ public static function between($subject, $from, $to) return static::beforeLast(static::after($subject, $from), $to); } + /** + * Get the smallest possible portion of a string between two given values. + * + * @param string $subject + * @param string $from + * @param string $to + * @return string + */ + public static function betweenFirst($subject, $from, $to) + { + if ($from === '' || $to === '') { + return $subject; + } + + return static::before(static::after($subject, $from), $to); + } + /** * Convert a value to camel case. * @@ -188,13 +220,26 @@ public static function camel($value) * Determine if a given string contains a given substring. * * @param string $haystack - * @param string|string[] $needles + * @param string|iterable $needles + * @param bool $ignoreCase * @return bool */ - public static function contains($haystack, $needles) + public static function contains($haystack, $needles, $ignoreCase = false) { - foreach ((array) $needles as $needle) { - if ($needle !== '' && mb_strpos($haystack, $needle) !== false) { + if ($ignoreCase) { + $haystack = mb_strtolower($haystack); + } + + if (! is_iterable($needles)) { + $needles = (array) $needles; + } + + foreach ($needles as $needle) { + if ($ignoreCase) { + $needle = mb_strtolower($needle); + } + + if ($needle !== '' && str_contains($haystack, $needle)) { return true; } } @@ -206,13 +251,14 @@ public static function contains($haystack, $needles) * Determine if a given string contains all array values. * * @param string $haystack - * @param string[] $needles + * @param iterable $needles + * @param bool $ignoreCase * @return bool */ - public static function containsAll($haystack, array $needles) + public static function containsAll($haystack, $needles, $ignoreCase = false) { foreach ($needles as $needle) { - if (! static::contains($haystack, $needle)) { + if (! static::contains($haystack, $needle, $ignoreCase)) { return false; } } @@ -224,16 +270,17 @@ public static function containsAll($haystack, array $needles) * Determine if a given string ends with a given substring. * * @param string $haystack - * @param string|string[] $needles + * @param string|iterable $needles * @return bool */ public static function endsWith($haystack, $needles) { - foreach ((array) $needles as $needle) { - if ( - $needle !== '' && $needle !== null - && substr($haystack, -strlen($needle)) === (string) $needle - ) { + if (! is_iterable($needles)) { + $needles = (array) $needles; + } + + foreach ($needles as $needle) { + if ((string) $needle !== '' && str_ends_with($haystack, $needle)) { return true; } } @@ -241,6 +288,42 @@ public static function endsWith($haystack, $needles) return false; } + /** + * Extracts an excerpt from text that matches the first instance of a phrase. + * + * @param string $text + * @param string $phrase + * @param array $options + * @return string|null + */ + public static function excerpt($text, $phrase = '', $options = []) + { + $radius = $options['radius'] ?? 100; + $omission = $options['omission'] ?? '...'; + + preg_match('/^(.*?)('.preg_quote((string) $phrase).')(.*)$/iu', (string) $text, $matches); + + if (empty($matches)) { + return null; + } + + $start = ltrim($matches[1]); + + $start = str(mb_substr($start, max(mb_strlen($start, 'UTF-8') - $radius, 0), $radius, 'UTF-8'))->ltrim()->unless( + fn ($startWithRadius) => $startWithRadius->exactly($start), + fn ($startWithRadius) => $startWithRadius->prepend($omission), + ); + + $end = rtrim($matches[3]); + + $end = str(mb_substr($end, 0, $radius, 'UTF-8'))->rtrim()->unless( + fn ($endWithRadius) => $endWithRadius->exactly($end), + fn ($endWithRadius) => $endWithRadius->append($omission), + ); + + return $start->append($matches[2], $end)->toString(); + } + /** * Cap a string with a single instance of a given value. * @@ -255,30 +338,41 @@ public static function finish($value, $cap) return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap; } + /** + * Wrap the string with the given strings. + * + * @param string $value + * @param string $before + * @param string|null $after + * @return string + */ + public static function wrap($value, $before, $after = null) + { + return $before.$value.($after ??= $before); + } + /** * Determine if a given string matches a given pattern. * - * @param string|array $pattern + * @param string|iterable $pattern * @param string $value * @return bool */ public static function is($pattern, $value) { - $patterns = Arr::wrap($pattern); - $value = (string) $value; - if (empty($patterns)) { - return false; + if (! is_iterable($pattern)) { + $pattern = [$pattern]; } - foreach ($patterns as $pattern) { + foreach ($pattern as $pattern) { $pattern = (string) $pattern; // If the given value is an exact match we can of course return true right // from the beginning. Otherwise, we will translate asterisks and do an // actual pattern match against the two strings to see if they match. - if ($pattern == $value) { + if ($pattern === $value) { return true; } @@ -308,6 +402,27 @@ public static function isAscii($value) return ASCII::is_ascii((string) $value); } + /** + * Determine if a given string is valid JSON. + * + * @param string $value + * @return bool + */ + public static function isJson($value) + { + if (! is_string($value)) { + return false; + } + + try { + json_decode($value, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException) { + return false; + } + + return true; + } + /** * Determine if a given string is a valid UUID. * @@ -323,6 +438,21 @@ public static function isUuid($value) return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; } + /** + * Determine if a given string is a valid ULID. + * + * @param string $value + * @return bool + */ + public static function isUlid($value) + { + if (! is_string($value)) { + return false; + } + + return Ulid::isValid($value); + } + /** * Convert a string to kebab case. * @@ -408,7 +538,26 @@ public static function markdown($string, array $options = []) { $converter = new GithubFlavoredMarkdownConverter($options); - return (string) $converter->convertToHtml($string); + return (string) $converter->convert($string); + } + + /** + * Converts inline Markdown into HTML. + * + * @param string $string + * @param array $options + * @return string + */ + public static function inlineMarkdown($string, array $options = []) + { + $environment = new Environment($options); + + $environment->addExtension(new GithubFlavoredMarkdownExtension()); + $environment->addExtension(new InlinesOnlyExtension()); + + $converter = new MarkdownConverter($environment); + + return (string) $converter->convert($string); } /** @@ -427,10 +576,6 @@ public static function mask($string, $character, $index, $length = null, $encodi return $string; } - if (is_null($length) && PHP_MAJOR_VERSION < 8) { - $length = mb_strlen($string, $encoding); - } - $segment = mb_substr($string, $index, $length, $encoding); if ($segment === '') { @@ -497,7 +642,13 @@ public static function matchAll($pattern, $subject) */ public static function padBoth($value, $length, $pad = ' ') { - return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_BOTH); + $short = max(0, $length - mb_strlen($value)); + $shortLeft = floor($short / 2); + $shortRight = ceil($short / 2); + + return mb_substr(str_repeat($pad, $shortLeft), 0, $shortLeft). + $value. + mb_substr(str_repeat($pad, $shortRight), 0, $shortRight); } /** @@ -510,7 +661,9 @@ public static function padBoth($value, $length, $pad = ' ') */ public static function padLeft($value, $length, $pad = ' ') { - return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_LEFT); + $short = max(0, $length - mb_strlen($value)); + + return mb_substr(str_repeat($pad, $short), 0, $short).$value; } /** @@ -523,7 +676,9 @@ public static function padLeft($value, $length, $pad = ' ') */ public static function padRight($value, $length, $pad = ' ') { - return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_RIGHT); + $short = max(0, $length - mb_strlen($value)); + + return $value.mb_substr(str_repeat($pad, $short), 0, $short); } /** @@ -574,17 +729,76 @@ public static function pluralStudly($value, $count = 2) */ public static function random($length = 16) { - $string = ''; + return (static::$randomStringFactory ?? function ($length) { + $string = ''; - while (($len = strlen($string)) < $length) { - $size = $length - $len; + while (($len = strlen($string)) < $length) { + $size = $length - $len; - $bytes = random_bytes($size); + $bytesSize = (int) ceil($size / 3) * 3; - $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); - } + $bytes = random_bytes($bytesSize); - return $string; + $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); + } + + return $string; + })($length); + } + + /** + * Set the callable that will be used to generate random strings. + * + * @param callable|null $factory + * @return void + */ + public static function createRandomStringsUsing(callable $factory = null) + { + static::$randomStringFactory = $factory; + } + + /** + * Set the sequence that will be used to generate random strings. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function createRandomStringsUsingSequence(array $sequence, $whenMissing = null) + { + $next = 0; + + $whenMissing ??= function ($length) use (&$next) { + $factoryCache = static::$randomStringFactory; + + static::$randomStringFactory = null; + + $randomString = static::random($length); + + static::$randomStringFactory = $factoryCache; + + $next++; + + return $randomString; + }; + + static::createRandomStringsUsing(function ($length) use (&$next, $sequence, $whenMissing) { + if (array_key_exists($next, $sequence)) { + return $sequence[$next++]; + } + + return $whenMissing($length); + }); + } + + /** + * Indicate that random strings should be created normally and not using a custom factory. + * + * @return void + */ + public static function createRandomStringsNormally() + { + static::$randomStringFactory = null; } /** @@ -603,12 +817,16 @@ public static function repeat(string $string, int $times) * Replace a given value in the string sequentially with an array. * * @param string $search - * @param array $replace + * @param iterable $replace * @param string $subject * @return string */ - public static function replaceArray($search, array $replace, $subject) + public static function replaceArray($search, $replace, $subject) { + if ($replace instanceof Traversable) { + $replace = collect($replace)->all(); + } + $segments = explode($search, $subject); $result = array_shift($segments); @@ -623,13 +841,25 @@ public static function replaceArray($search, array $replace, $subject) /** * Replace the given value in the given string. * - * @param string|string[] $search - * @param string|string[] $replace - * @param string|string[] $subject + * @param string|iterable $search + * @param string|iterable $replace + * @param string|iterable $subject * @return string */ public static function replace($search, $replace, $subject) { + if ($search instanceof Traversable) { + $search = collect($search)->all(); + } + + if ($replace instanceof Traversable) { + $replace = collect($replace)->all(); + } + + if ($subject instanceof Traversable) { + $subject = collect($subject)->all(); + } + return str_replace($search, $replace, $subject); } @@ -643,6 +873,8 @@ public static function replace($search, $replace, $subject) */ public static function replaceFirst($search, $replace, $subject) { + $search = (string) $search; + if ($search === '') { return $subject; } @@ -682,13 +914,17 @@ public static function replaceLast($search, $replace, $subject) /** * Remove any occurrence of the given string in the subject. * - * @param string|array $search + * @param string|iterable $search * @param string $subject * @param bool $caseSensitive * @return string */ public static function remove($search, $subject, $caseSensitive = true) { + if ($search instanceof Traversable) { + $search = collect($search)->all(); + } + $subject = $caseSensitive ? str_replace($search, '', $subject) : str_ireplace($search, '', $subject); @@ -754,8 +990,8 @@ public static function headline($value) $parts = explode(' ', $value); $parts = count($parts) > 1 - ? $parts = array_map([static::class, 'title'], $parts) - : $parts = array_map([static::class, 'title'], static::ucsplit(implode('_', $parts))); + ? array_map([static::class, 'title'], $parts) + : array_map([static::class, 'title'], static::ucsplit(implode('_', $parts))); $collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts)); @@ -779,9 +1015,10 @@ public static function singular($value) * @param string $title * @param string $separator * @param string|null $language + * @param array $dictionary * @return string */ - public static function slug($title, $separator = '-', $language = 'en') + public static function slug($title, $separator = '-', $language = 'en', $dictionary = ['@' => 'at']) { $title = $language ? static::ascii($title, $language) : $title; @@ -790,10 +1027,14 @@ public static function slug($title, $separator = '-', $language = 'en') $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title); - // Replace @ with the word 'at' - $title = str_replace('@', $separator.'at'.$separator, $title); + // Replace dictionary words + foreach ($dictionary as $key => $value) { + $dictionary[$key] = $separator.$value.$separator; + } + + $title = str_replace(array_keys($dictionary), array_values($dictionary), $title); - // Remove all characters that are not the separator, letters, numbers, or whitespace. + // Remove all characters that are not the separator, letters, numbers, or whitespace $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', static::lower($title)); // Replace all separator characters and whitespace by a single separator @@ -826,17 +1067,32 @@ public static function snake($value, $delimiter = '_') return static::$snakeCache[$key][$delimiter] = $value; } + /** + * Remove all "extra" blank space from the given string. + * + * @param string $value + * @return string + */ + public static function squish($value) + { + return preg_replace('~(\s|\x{3164})+~u', ' ', preg_replace('~^[\s\x{FEFF}]+|[\s\x{FEFF}]+$~u', '', $value)); + } + /** * Determine if a given string starts with a given substring. * * @param string $haystack - * @param string|string[] $needles + * @param string|iterable $needles * @return bool */ public static function startsWith($haystack, $needles) { - foreach ((array) $needles as $needle) { - if ((string) $needle !== '' && strncmp($haystack, $needle, strlen($needle)) === 0) { + if (! is_iterable($needles)) { + $needles = [$needles]; + } + + foreach ($needles as $needle) { + if ((string) $needle !== '' && str_starts_with($haystack, $needle)) { return true; } } @@ -860,9 +1116,7 @@ public static function studly($value) $words = explode(' ', static::replace(['-', '_'], ' ', $value)); - $studlyWords = array_map(function ($word) { - return static::ucfirst($word); - }, $words); + $studlyWords = array_map(fn ($word) => static::ucfirst($word), $words); return static::$studlyCache[$key] = implode($studlyWords); } @@ -873,11 +1127,12 @@ public static function studly($value) * @param string $string * @param int $start * @param int|null $length + * @param string $encoding * @return string */ - public static function substr($string, $start, $length = null) + public static function substr($string, $start, $length = null, $encoding = 'UTF-8') { - return mb_substr($string, $start, $length, 'UTF-8'); + return mb_substr($string, $start, $length, $encoding); } /** @@ -893,19 +1148,19 @@ public static function substrCount($haystack, $needle, $offset = 0, $length = nu { if (! is_null($length)) { return substr_count($haystack, $needle, $offset, $length); - } else { - return substr_count($haystack, $needle, $offset); } + + return substr_count($haystack, $needle, $offset); } /** * Replace text within a portion of a string. * - * @param string|array $string - * @param string|array $replace - * @param array|int $offset - * @param array|int|null $length - * @return string|array + * @param string|string[] $string + * @param string|string[] $replace + * @param int|int[] $offset + * @param int|int[]|null $length + * @return string|string[] */ public static function substrReplace($string, $replace, $offset = 0, $length = null) { @@ -928,6 +1183,17 @@ public static function swap(array $map, $subject) return strtr($subject, $map); } + /** + * Make a string's first character lowercase. + * + * @param string $string + * @return string + */ + public static function lcfirst($string) + { + return static::lower(static::substr($string, 0, 1)).static::substr($string, 1); + } + /** * Make a string's first character uppercase. * @@ -943,7 +1209,7 @@ public static function ucfirst($string) * Split a string into pieces by uppercase characters. * * @param string $string - * @return array + * @return string[] */ public static function ucsplit($string) { @@ -954,11 +1220,12 @@ public static function ucsplit($string) * Get the number of words a string contains. * * @param string $string + * @param string|null $characters * @return int */ - public static function wordCount($string) + public static function wordCount($string, $characters = null) { - return str_word_count($string); + return str_word_count($string, 0, $characters); } /** @@ -1009,6 +1276,63 @@ public static function createUuidsUsing(callable $factory = null) static::$uuidFactory = $factory; } + /** + * Set the sequence that will be used to generate UUIDs. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function createUuidsUsingSequence(array $sequence, $whenMissing = null) + { + $next = 0; + + $whenMissing ??= function () use (&$next) { + $factoryCache = static::$uuidFactory; + + static::$uuidFactory = null; + + $uuid = static::uuid(); + + static::$uuidFactory = $factoryCache; + + $next++; + + return $uuid; + }; + + static::createUuidsUsing(function () use (&$next, $sequence, $whenMissing) { + if (array_key_exists($next, $sequence)) { + return $sequence[$next++]; + } + + return $whenMissing(); + }); + } + + /** + * Always return the same UUID when generating new UUIDs. + * + * @param \Closure|null $callback + * @return \Ramsey\Uuid\UuidInterface + */ + public static function freezeUuids(Closure $callback = null) + { + $uuid = Str::uuid(); + + Str::createUuidsUsing(fn () => $uuid); + + if ($callback !== null) { + try { + $callback($uuid); + } finally { + Str::createUuidsNormally(); + } + } + + return $uuid; + } + /** * Indicate that UUIDs should be created normally and not using a custom factory. * @@ -1019,6 +1343,16 @@ public static function createUuidsNormally() static::$uuidFactory = null; } + /** + * Generate a ULID. + * + * @return \Symfony\Component\Uid\Ulid + */ + public static function ulid() + { + return new Ulid(); + } + /** * Remove all strings from the casing caches. * diff --git a/lam/lib/3rdParty/composer/illuminate/support/Stringable.php b/lam/lib/3rdParty/composer/illuminate/support/Stringable.php index 414be0c27..74535706f 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Stringable.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Stringable.php @@ -3,6 +3,7 @@ namespace Illuminate\Support; use Closure; +use Illuminate\Support\Facades\Date; use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\Macroable; use Illuminate\Support\Traits\Tappable; @@ -56,7 +57,7 @@ public function afterLast($search) /** * Append the given values to the string. * - * @param array $values + * @param string ...$values * @return static */ public function append(...$values) @@ -64,6 +65,17 @@ public function append(...$values) return new static($this->value.implode('', $values)); } + /** + * Append a new line to the string. + * + * @param int $count + * @return $this + */ + public function newLine($count = 1) + { + return $this->append(str_repeat(PHP_EOL, $count)); + } + /** * Transliterate a UTF-8 value to ASCII. * @@ -130,6 +142,18 @@ public function between($from, $to) return new static(Str::between($this->value, $from, $to)); } + /** + * Get the smallest possible portion of a string between two given values. + * + * @param string $from + * @param string $to + * @return static + */ + public function betweenFirst($from, $to) + { + return new static(Str::betweenFirst($this->value, $from, $to)); + } + /** * Convert a value to camel case. * @@ -143,23 +167,25 @@ public function camel() /** * Determine if a given string contains a given substring. * - * @param string|array $needles + * @param string|iterable $needles + * @param bool $ignoreCase * @return bool */ - public function contains($needles) + public function contains($needles, $ignoreCase = false) { - return Str::contains($this->value, $needles); + return Str::contains($this->value, $needles, $ignoreCase); } /** * Determine if a given string contains all array values. * - * @param array $needles + * @param iterable $needles + * @param bool $ignoreCase * @return bool */ - public function containsAll(array $needles) + public function containsAll($needles, $ignoreCase = false) { - return Str::containsAll($this->value, $needles); + return Str::containsAll($this->value, $needles, $ignoreCase); } /** @@ -176,7 +202,7 @@ public function dirname($levels = 1) /** * Determine if a given string ends with a given substring. * - * @param string|array $needles + * @param string|iterable $needles * @return bool */ public function endsWith($needles) @@ -187,14 +213,30 @@ public function endsWith($needles) /** * Determine if the string is an exact match with the given value. * - * @param string $value + * @param \Illuminate\Support\Stringable|string $value * @return bool */ public function exactly($value) { + if ($value instanceof Stringable) { + $value = $value->toString(); + } + return $this->value === $value; } + /** + * Extracts an excerpt from text that matches the first instance of a phrase. + * + * @param string $phrase + * @param array $options + * @return string|null + */ + public function excerpt($phrase = '', $options = []) + { + return Str::excerpt($this->value, $phrase, $options); + } + /** * Explode the string into an array. * @@ -240,7 +282,7 @@ public function finish($cap) /** * Determine if a given string matches a given pattern. * - * @param string|array $pattern + * @param string|iterable $pattern * @return bool */ public function is($pattern) @@ -258,6 +300,16 @@ public function isAscii() return Str::isAscii($this->value); } + /** + * Determine if a given string is valid JSON. + * + * @return bool + */ + public function isJson() + { + return Str::isJson($this->value); + } + /** * Determine if a given string is a valid UUID. * @@ -268,6 +320,16 @@ public function isUuid() return Str::isUuid($this->value); } + /** + * Determine if a given string is a valid ULID. + * + * @return bool + */ + public function isUlid() + { + return Str::isUlid($this->value); + } + /** * Determine if the given string is empty. * @@ -301,7 +363,7 @@ public function kebab() /** * Return the length of the given string. * - * @param string $encoding + * @param string|null $encoding * @return int */ public function length($encoding = null) @@ -342,6 +404,17 @@ public function markdown(array $options = []) return new static(Str::markdown($this->value, $options)); } + /** + * Convert inline Markdown into HTML. + * + * @param array $options + * @return static + */ + public function inlineMarkdown(array $options = []) + { + return new static(Str::inlineMarkdown($this->value, $options)); + } + /** * Masks a portion of a string with a repeated character. * @@ -429,7 +502,7 @@ public function padRight($length, $pad = ' ') * Parse a Class@method style callback into class and method. * * @param string|null $default - * @return array + * @return array */ public function parseCallback($default = null) { @@ -444,13 +517,13 @@ public function parseCallback($default = null) */ public function pipe(callable $callback) { - return new static(call_user_func($callback, $this)); + return new static($callback($this)); } /** * Get the plural form of an English word. * - * @param int $count + * @param int|array|\Countable $count * @return static */ public function plural($count = 2) @@ -461,7 +534,7 @@ public function plural($count = 2) /** * Pluralize the last word of an English, studly caps case string. * - * @param int $count + * @param int|array|\Countable $count * @return static */ public function pluralStudly($count = 2) @@ -472,7 +545,7 @@ public function pluralStudly($count = 2) /** * Prepend the given values to the string. * - * @param array $values + * @param string ...$values * @return static */ public function prepend(...$values) @@ -483,7 +556,7 @@ public function prepend(...$values) /** * Remove any occurrence of the given string in the subject. * - * @param string|array $search + * @param string|iterable $search * @param bool $caseSensitive * @return static */ @@ -510,14 +583,14 @@ public function reverse() */ public function repeat(int $times) { - return new static(Str::repeat($this->value, $times)); + return new static(str_repeat($this->value, $times)); } /** * Replace the given value in the given string. * - * @param string|string[] $search - * @param string|string[] $replace + * @param string|iterable $search + * @param string|iterable $replace * @return static */ public function replace($search, $replace) @@ -529,10 +602,10 @@ public function replace($search, $replace) * Replace a given value in the string sequentially with an array. * * @param string $search - * @param array $replace + * @param iterable $replace * @return static */ - public function replaceArray($search, array $replace) + public function replaceArray($search, $replace) { return new static(Str::replaceArray($search, $replace, $this->value)); } @@ -589,6 +662,16 @@ public function scan($format) return collect(sscanf($this->value, $format)); } + /** + * Remove all "extra" blank space from the given string. + * + * @return static + */ + public function squish() + { + return new static(Str::squish($this->value)); + } + /** * Begin a string with a single instance of a given value. * @@ -656,11 +739,12 @@ public function singular() * * @param string $separator * @param string|null $language + * @param array $dictionary * @return static */ - public function slug($separator = '-', $language = 'en') + public function slug($separator = '-', $language = 'en', $dictionary = ['@' => 'at']) { - return new static(Str::slug($this->value, $separator, $language)); + return new static(Str::slug($this->value, $separator, $language, $dictionary)); } /** @@ -677,7 +761,7 @@ public function snake($delimiter = '_') /** * Determine if a given string starts with a given substring. * - * @param string|array $needles + * @param string|iterable $needles * @return bool */ public function startsWith($needles) @@ -700,32 +784,33 @@ public function studly() * * @param int $start * @param int|null $length + * @param string $encoding * @return static */ - public function substr($start, $length = null) + public function substr($start, $length = null, $encoding = 'UTF-8') { - return new static(Str::substr($this->value, $start, $length)); + return new static(Str::substr($this->value, $start, $length, $encoding)); } /** * Returns the number of substring occurrences. * * @param string $needle - * @param int|null $offset + * @param int $offset * @param int|null $length * @return int */ - public function substrCount($needle, $offset = null, $length = null) + public function substrCount($needle, $offset = 0, $length = null) { - return Str::substrCount($this->value, $needle, $offset ?? 0, $length); + return Str::substrCount($this->value, $needle, $offset, $length); } /** * Replace text within a portion of a string. * - * @param string|array $replace - * @param array|int $offset - * @param array|int|null $length + * @param string|string[] $replace + * @param int|int[] $offset + * @param int|int[]|null $length * @return static */ public function substrReplace($replace, $offset = 0, $length = null) @@ -777,6 +862,16 @@ public function rtrim($characters = null) return new static(rtrim(...array_merge([$this->value], func_get_args()))); } + /** + * Make a string's first character lowercase. + * + * @return static + */ + public function lcfirst() + { + return new static(Str::lcfirst($this->value)); + } + /** * Make a string's first character uppercase. * @@ -800,7 +895,7 @@ public function ucsplit() /** * Execute the given callback if the string contains a given substring. * - * @param string|array $needles + * @param string|iterable $needles * @param callable $callback * @param callable|null $default * @return static @@ -813,7 +908,7 @@ public function whenContains($needles, $callback, $default = null) /** * Execute the given callback if the string contains all array values. * - * @param array $needles + * @param iterable $needles * @param callable $callback * @param callable|null $default * @return static @@ -850,7 +945,7 @@ public function whenNotEmpty($callback, $default = null) /** * Execute the given callback if the string ends with a given substring. * - * @param string|array $needles + * @param string|iterable $needles * @param callable $callback * @param callable|null $default * @return static @@ -873,10 +968,23 @@ public function whenExactly($value, $callback, $default = null) return $this->when($this->exactly($value), $callback, $default); } + /** + * Execute the given callback if the string is not an exact match with the given value. + * + * @param string $value + * @param callable $callback + * @param callable|null $default + * @return static + */ + public function whenNotExactly($value, $callback, $default = null) + { + return $this->when(! $this->exactly($value), $callback, $default); + } + /** * Execute the given callback if the string matches a given pattern. * - * @param string|array $pattern + * @param string|iterable $pattern * @param callable $callback * @param callable|null $default * @return static @@ -910,10 +1018,22 @@ public function whenIsUuid($callback, $default = null) return $this->when($this->isUuid(), $callback, $default); } + /** + * Execute the given callback if the string is a valid ULID. + * + * @param callable $callback + * @param callable|null $default + * @return static + */ + public function whenIsUlid($callback, $default = null) + { + return $this->when($this->isUlid(), $callback, $default); + } + /** * Execute the given callback if the string starts with a given substring. * - * @param string|array $needles + * @param string|iterable $needles * @param callable $callback * @param callable|null $default * @return static @@ -951,11 +1071,24 @@ public function words($words = 100, $end = '...') /** * Get the number of words a string contains. * + * @param string|null $characters * @return int */ - public function wordCount() + public function wordCount($characters = null) { - return str_word_count($this->value); + return Str::wordCount($this->value, $characters); + } + + /** + * Wrap the string with the given strings. + * + * @param string $before + * @param string|null $after + * @return static + */ + public function wrap($before, $after = null) + { + return new static(Str::wrap($this->value, $before, $after)); } /** @@ -992,13 +1125,82 @@ public function dd() exit(1); } + /** + * Get the underlying string value. + * + * @return string + */ + public function value() + { + return $this->toString(); + } + + /** + * Get the underlying string value. + * + * @return string + */ + public function toString() + { + return $this->value; + } + + /** + * Get the underlying string value as an integer. + * + * @return int + */ + public function toInteger() + { + return intval($this->value); + } + + /** + * Get the underlying string value as a float. + * + * @return float + */ + public function toFloat() + { + return floatval($this->value); + } + + /** + * Get the underlying string value as a boolean. + * + * Returns true when value is "1", "true", "on", and "yes". Otherwise, returns false. + * + * @return bool + */ + public function toBoolean() + { + return filter_var($this->value, FILTER_VALIDATE_BOOLEAN); + } + + /** + * Get the underlying string value as a Carbon instance. + * + * @param string|null $format + * @param string|null $tz + * @return \Illuminate\Support\Carbon + * + * @throws \Carbon\Exceptions\InvalidFormatException + */ + public function toDate($format = null, $tz = null) + { + if (is_null($format)) { + return Date::parse($this->value, $tz); + } + + return Date::createFromFormat($format, $this->value, $tz); + } + /** * Convert the object to a string when JSON encoded. * * @return string */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): string { return $this->__toString(); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchFake.php new file mode 100644 index 000000000..607168ba9 --- /dev/null +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchFake.php @@ -0,0 +1,163 @@ +id = $id; + $this->name = $name; + $this->totalJobs = $totalJobs; + $this->pendingJobs = $pendingJobs; + $this->failedJobs = $failedJobs; + $this->failedJobIds = $failedJobIds; + $this->options = $options; + $this->createdAt = $createdAt; + $this->cancelledAt = $cancelledAt; + $this->finishedAt = $finishedAt; + } + + /** + * Get a fresh instance of the batch represented by this ID. + * + * @return self + */ + public function fresh() + { + return $this; + } + + /** + * Add additional jobs to the batch. + * + * @param \Illuminate\Support\Enumerable|object|array $jobs + * @return self + */ + public function add($jobs) + { + foreach ($jobs as $job) { + $this->added[] = $job; + } + + return $this; + } + + /** + * Record that a job within the batch finished successfully, executing any callbacks if necessary. + * + * @param string $jobId + * @return void + */ + public function recordSuccessfulJob(string $jobId) + { + // + } + + /** + * Decrement the pending jobs for the batch. + * + * @param string $jobId + * @return \Illuminate\Bus\UpdatedBatchJobCounts + */ + public function decrementPendingJobs(string $jobId) + { + // + } + + /** + * Record that a job within the batch failed to finish successfully, executing any callbacks if necessary. + * + * @param string $jobId + * @param \Throwable $e + * @return void + */ + public function recordFailedJob(string $jobId, $e) + { + // + } + + /** + * Increment the failed jobs for the batch. + * + * @param string $jobId + * @return \Illuminate\Bus\UpdatedBatchJobCounts + */ + public function incrementFailedJobs(string $jobId) + { + return new UpdatedBatchJobCounts; + } + + /** + * Cancel the batch. + * + * @return void + */ + public function cancel() + { + $this->cancelledAt = Carbon::now(); + } + + /** + * Delete the batch from storage. + * + * @return void + */ + public function delete() + { + $this->deleted = true; + } + + /** + * Determine if the batch has been deleted. + * + * @return bool + */ + public function deleted() + { + return $this->deleted; + } +} diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchRepositoryFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchRepositoryFake.php index d9661334c..021c73f27 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchRepositoryFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BatchRepositoryFake.php @@ -4,15 +4,20 @@ use Carbon\CarbonImmutable; use Closure; -use Illuminate\Bus\Batch; use Illuminate\Bus\BatchRepository; use Illuminate\Bus\PendingBatch; use Illuminate\Bus\UpdatedBatchJobCounts; -use Illuminate\Support\Facades\Facade; use Illuminate\Support\Str; class BatchRepositoryFake implements BatchRepository { + /** + * The batches stored in the repository. + * + * @var \Illuminate\Bus\Batch[] + */ + protected $batches = []; + /** * Retrieve a list of batches. * @@ -22,7 +27,7 @@ class BatchRepositoryFake implements BatchRepository */ public function get($limit, $before) { - return []; + return $this->batches; } /** @@ -33,7 +38,7 @@ public function get($limit, $before) */ public function find(string $batchId) { - // + return $this->batches[$batchId] ?? null; } /** @@ -44,10 +49,10 @@ public function find(string $batchId) */ public function store(PendingBatch $batch) { - return new Batch( - new QueueFake(Facade::getFacadeApplication()), - $this, - (string) Str::orderedUuid(), + $id = (string) Str::orderedUuid(); + + $this->batches[$id] = new BatchFake( + $id, $batch->name, count($batch->jobs), count($batch->jobs), @@ -58,6 +63,8 @@ public function store(PendingBatch $batch) null, null ); + + return $this->batches[$id]; } /** @@ -104,7 +111,9 @@ public function incrementFailedJobs(string $batchId, string $jobId) */ public function markAsFinished(string $batchId) { - // + if (isset($this->batches[$batchId])) { + $this->batches[$batchId]->finishedAt = now(); + } } /** @@ -115,7 +124,9 @@ public function markAsFinished(string $batchId) */ public function cancel(string $batchId) { - // + if (isset($this->batches[$batchId])) { + $this->batches[$batchId]->cancel(); + } } /** @@ -126,7 +137,7 @@ public function cancel(string $batchId) */ public function delete(string $batchId) { - // + unset($this->batches[$batchId]); } /** diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BusFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BusFake.php index 122252d8f..9da1fac7c 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BusFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/BusFake.php @@ -3,6 +3,7 @@ namespace Illuminate\Support\Testing\Fakes; use Closure; +use Illuminate\Bus\BatchRepository; use Illuminate\Bus\PendingBatch; use Illuminate\Contracts\Bus\QueueingDispatcher; use Illuminate\Support\Arr; @@ -26,7 +27,21 @@ class BusFake implements QueueingDispatcher * * @var array */ - protected $jobsToFake; + protected $jobsToFake = []; + + /** + * The job types that should be dispatched instead of faked. + * + * @var array + */ + protected $jobsToDispatch = []; + + /** + * The fake repository to track batched jobs. + * + * @var \Illuminate\Bus\BatchRepository + */ + protected $batchRepository; /** * The commands that have been dispatched. @@ -61,13 +76,27 @@ class BusFake implements QueueingDispatcher * * @param \Illuminate\Contracts\Bus\QueueingDispatcher $dispatcher * @param array|string $jobsToFake + * @param \Illuminate\Bus\BatchRepository|null $batchRepository * @return void */ - public function __construct(QueueingDispatcher $dispatcher, $jobsToFake = []) + public function __construct(QueueingDispatcher $dispatcher, $jobsToFake = [], BatchRepository $batchRepository = null) { $this->dispatcher = $dispatcher; - $this->jobsToFake = Arr::wrap($jobsToFake); + $this->batchRepository = $batchRepository ?: new BatchRepositoryFake; + } + + /** + * Specify the jobs that should be dispatched instead of faked. + * + * @param array|string $jobsToDispatch + * @return void + */ + public function except($jobsToDispatch) + { + $this->jobsToDispatch = array_merge($this->jobsToDispatch, Arr::wrap($jobsToDispatch)); + + return $this; } /** @@ -98,15 +127,21 @@ public function assertDispatched($command, $callback = null) /** * Assert if a job was pushed a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedTimes($command, $times = 1) { - $count = $this->dispatched($command)->count() + - $this->dispatchedAfterResponse($command)->count() + - $this->dispatchedSync($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatched($command, $callback)->count() + + $this->dispatchedAfterResponse($command, $callback)->count() + + $this->dispatchedSync($command, $callback)->count(); PHPUnit::assertSame( $times, $count, @@ -171,13 +206,19 @@ public function assertDispatchedSync($command, $callback = null) /** * Assert if a job was pushed synchronously a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedSyncTimes($command, $times = 1) { - $count = $this->dispatchedSync($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatchedSync($command, $callback)->count(); PHPUnit::assertSame( $times, $count, @@ -230,13 +271,19 @@ public function assertDispatchedAfterResponse($command, $callback = null) /** * Assert if a job was pushed after the response was sent a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedAfterResponseTimes($command, $times = 1) { - $count = $this->dispatchedAfterResponse($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatchedAfterResponse($command, $callback)->count(); PHPUnit::assertSame( $times, $count, @@ -351,14 +398,12 @@ public function assertDispatchedWithoutChain($command, $callback = null) */ protected function assertDispatchedWithChainOfObjects($command, $expectedChain, $callback) { - $chain = collect($expectedChain)->map(function ($job) { - return serialize($job); - })->all(); + $chain = collect($expectedChain)->map(fn ($job) => serialize($job))->all(); PHPUnit::assertTrue( - $this->dispatched($command, $callback)->filter(function ($job) use ($chain) { - return $job->chained == $chain; - })->isNotEmpty(), + $this->dispatched($command, $callback)->filter( + fn ($job) => $job->chained == $chain + )->isNotEmpty(), 'The expected chain was not dispatched.' ); } @@ -374,12 +419,12 @@ protected function assertDispatchedWithChainOfObjects($command, $expectedChain, protected function assertDispatchedWithChainOfClasses($command, $expectedChain, $callback) { $matching = $this->dispatched($command, $callback)->map->chained->map(function ($chain) { - return collect($chain)->map(function ($job) { - return get_class(unserialize($job)); - }); - })->filter(function ($chain) use ($expectedChain) { - return $chain->all() === $expectedChain; - }); + return collect($chain)->map( + fn ($job) => get_class(unserialize($job)) + ); + })->filter( + fn ($chain) => $chain->all() === $expectedChain + ); PHPUnit::assertTrue( $matching->isNotEmpty(), 'The expected chain was not dispatched.' @@ -394,9 +439,7 @@ protected function assertDispatchedWithChainOfClasses($command, $expectedChain, */ protected function isChainOfObjects($chain) { - return ! collect($chain)->contains(function ($job) { - return ! is_object($job); - }); + return ! collect($chain)->contains(fn ($job) => ! is_object($job)); } /** @@ -426,6 +469,16 @@ public function assertBatchCount($count) ); } + /** + * Assert that no batched jobs were dispatched. + * + * @return void + */ + public function assertNothingBatched() + { + PHPUnit::assertEmpty($this->batches, 'Batched jobs were dispatched unexpectedly.'); + } + /** * Get all of the jobs matching a truth-test callback. * @@ -439,13 +492,9 @@ public function dispatched($command, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return collect($this->commands[$command])->filter(function ($command) use ($callback) { - return $callback($command); - }); + return collect($this->commands[$command])->filter(fn ($command) => $callback($command)); } /** @@ -461,13 +510,9 @@ public function dispatchedSync(string $command, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return collect($this->commandsSync[$command])->filter(function ($command) use ($callback) { - return $callback($command); - }); + return collect($this->commandsSync[$command])->filter(fn ($command) => $callback($command)); } /** @@ -483,13 +528,9 @@ public function dispatchedAfterResponse(string $command, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return collect($this->commandsAfterResponse[$command])->filter(function ($command) use ($callback) { - return $callback($command); - }); + return collect($this->commandsAfterResponse[$command])->filter(fn ($command) => $callback($command)); } /** @@ -504,9 +545,7 @@ public function batched(callable $callback) return collect(); } - return collect($this->batches)->filter(function ($batch) use ($callback) { - return $callback($batch); - }); + return collect($this->batches)->filter(fn ($batch) => $callback($batch)); } /** @@ -642,7 +681,7 @@ public function chain($jobs) */ public function findBatch(string $batchId) { - // + return $this->batchRepository->find($batchId); } /** @@ -656,6 +695,17 @@ public function batch($jobs) return new PendingBatchFake($this, Collection::wrap($jobs)); } + /** + * Dispatch an empty job batch for testing. + * + * @param string $name + * @return \Illuminate\Bus\Batch + */ + public function dispatchFakeBatch($name = '') + { + return $this->batch([])->name($name)->dispatch(); + } + /** * Record the fake pending batch dispatch. * @@ -666,7 +716,7 @@ public function recordPendingBatch(PendingBatch $pendingBatch) { $this->batches[] = $pendingBatch; - return (new BatchRepositoryFake)->store($pendingBatch); + return $this->batchRepository->store($pendingBatch); } /** @@ -677,6 +727,10 @@ public function recordPendingBatch(PendingBatch $pendingBatch) */ protected function shouldFakeJob($command) { + if ($this->shouldDispatchCommand($command)) { + return false; + } + if (empty($this->jobsToFake)) { return true; } @@ -689,6 +743,22 @@ protected function shouldFakeJob($command) })->isNotEmpty(); } + /** + * Determine if a command should be dispatched or not. + * + * @param mixed $command + * @return bool + */ + protected function shouldDispatchCommand($command) + { + return collect($this->jobsToDispatch) + ->filter(function ($job) use ($command) { + return $job instanceof Closure + ? $job($command) + : $job === get_class($command); + })->isNotEmpty(); + } + /** * Set the pipes commands should be piped through before dispatching. * diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/EventFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/EventFake.php index 436173e9d..3a16cef50 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/EventFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/EventFake.php @@ -26,7 +26,14 @@ class EventFake implements Dispatcher * * @var array */ - protected $eventsToFake; + protected $eventsToFake = []; + + /** + * The event types that should be dispatched instead of intercepted. + * + * @var array + */ + protected $eventsToDispatch = []; /** * All of the events that have been intercepted keyed by type. @@ -49,11 +56,27 @@ public function __construct(Dispatcher $dispatcher, $eventsToFake = []) $this->eventsToFake = Arr::wrap($eventsToFake); } + /** + * Specify the events that should be dispatched instead of faked. + * + * @param array|string $eventsToDispatch + * @return $this + */ + public function except($eventsToDispatch) + { + $this->eventsToDispatch = array_merge( + $this->eventsToDispatch, + Arr::wrap($eventsToDispatch) + ); + + return $this; + } + /** * Assert if an event has a listener attached to it. * * @param string $expectedEvent - * @param string $expectedListener + * @param string|array $expectedListener * @return void */ public function assertListening($expectedEvent, $expectedListener) @@ -62,13 +85,26 @@ public function assertListening($expectedEvent, $expectedListener) $actualListener = (new ReflectionFunction($listenerClosure)) ->getStaticVariables()['listener']; - if (is_string($actualListener) && Str::endsWith($actualListener, '@handle')) { - $actualListener = Str::parseCallback($actualListener)[0]; + $normalizedListener = $expectedListener; + + if (is_string($actualListener) && Str::contains($actualListener, '@')) { + $actualListener = Str::parseCallback($actualListener); + + if (is_string($expectedListener)) { + if (Str::contains($expectedListener, '@')) { + $normalizedListener = Str::parseCallback($expectedListener); + } else { + $normalizedListener = [ + $expectedListener, + method_exists($expectedListener, 'handle') ? 'handle' : '__invoke', + ]; + } + } } - if ($actualListener === $expectedListener || + if ($actualListener === $normalizedListener || ($actualListener instanceof Closure && - $expectedListener === Closure::class)) { + $normalizedListener === Closure::class)) { PHPUnit::assertTrue(true); return; @@ -172,13 +208,11 @@ public function dispatched($event, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return collect($this->events[$event])->filter(function ($arguments) use ($callback) { - return $callback(...$arguments); - }); + return collect($this->events[$event])->filter( + fn ($arguments) => $callback(...$arguments) + ); } /** @@ -277,6 +311,10 @@ public function dispatch($event, $payload = [], $halt = false) */ protected function shouldFakeEvent($eventName, $payload) { + if ($this->shouldDispatchEvent($eventName, $payload)) { + return false; + } + if (empty($this->eventsToFake)) { return true; } @@ -290,6 +328,28 @@ protected function shouldFakeEvent($eventName, $payload) ->isNotEmpty(); } + /** + * Determine whether an event should be dispatched or not. + * + * @param string $eventName + * @param mixed $payload + * @return bool + */ + protected function shouldDispatchEvent($eventName, $payload) + { + if (empty($this->eventsToDispatch)) { + return false; + } + + return collect($this->eventsToDispatch) + ->filter(function ($event) use ($eventName, $payload) { + return $event instanceof Closure + ? $event($eventName, $payload) + : $event === $eventName; + }) + ->isNotEmpty(); + } + /** * Remove a set of listeners from the dispatcher. * diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/MailFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/MailFake.php index fff5f8fcb..c95c15a55 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/MailFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/MailFake.php @@ -128,9 +128,9 @@ public function assertNothingOutgoing() */ public function assertNothingSent() { - $mailableNames = collect($this->mailables)->map(function ($mailable) { - return get_class($mailable); - })->join(', '); + $mailableNames = collect($this->mailables)->map( + fn ($mailable) => get_class($mailable) + )->join(', '); PHPUnit::assertEmpty($this->mailables, 'The following mailables were sent unexpectedly: '.$mailableNames); } @@ -197,9 +197,9 @@ public function assertNotQueued($mailable, $callback = null) */ public function assertNothingQueued() { - $mailableNames = collect($this->queuedMailables)->map(function ($mailable) { - return get_class($mailable); - })->join(', '); + $mailableNames = collect($this->queuedMailables)->map( + fn ($mailable) => get_class($mailable) + )->join(', '); PHPUnit::assertEmpty($this->queuedMailables, 'The following mailables were queued unexpectedly: '.$mailableNames); } @@ -219,13 +219,9 @@ public function sent($mailable, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return $this->mailablesOf($mailable)->filter(function ($mailable) use ($callback) { - return $callback($mailable); - }); + return $this->mailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable)); } /** @@ -254,13 +250,9 @@ public function queued($mailable, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return $this->queuedMailablesOf($mailable)->filter(function ($mailable) use ($callback) { - return $callback($mailable); - }); + return $this->queuedMailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable)); } /** @@ -282,9 +274,7 @@ public function hasQueued($mailable) */ protected function mailablesOf($type) { - return collect($this->mailables)->filter(function ($mailable) use ($type) { - return $mailable instanceof $type; - }); + return collect($this->mailables)->filter(fn ($mailable) => $mailable instanceof $type); } /** @@ -295,9 +285,7 @@ protected function mailablesOf($type) */ protected function queuedMailablesOf($type) { - return collect($this->queuedMailables)->filter(function ($mailable) use ($type) { - return $mailable instanceof $type; - }); + return collect($this->queuedMailables)->filter(fn ($mailable) => $mailable instanceof $type); } /** @@ -324,6 +312,17 @@ public function to($users) return (new PendingMailFake($this))->to($users); } + /** + * Begin the process of mailing a mailable class instance. + * + * @param mixed $users + * @return \Illuminate\Mail\PendingMail + */ + public function cc($users) + { + return (new PendingMailFake($this))->cc($users); + } + /** * Begin the process of mailing a mailable class instance. * diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/NotificationFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/NotificationFake.php index c7b12f42d..5991420d3 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/NotificationFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/NotificationFake.php @@ -158,6 +158,34 @@ public function assertNothingSent() PHPUnit::assertEmpty($this->notifications, 'Notifications were sent unexpectedly.'); } + /** + * Assert that no notifications were sent to the given notifiable. + * + * @param mixed $notifiable + * @return void + * + * @throws \Exception + */ + public function assertNothingSentTo($notifiable) + { + if (is_array($notifiable) || $notifiable instanceof Collection) { + if (count($notifiable) === 0) { + throw new Exception('No notifiable given.'); + } + + foreach ($notifiable as $singleNotifiable) { + $this->assertNothingSentTo($singleNotifiable); + } + + return; + } + + PHPUnit::assertEmpty( + $this->notifications[get_class($notifiable)][$notifiable->getKey()] ?? [], + 'Notifications were sent unexpectedly.', + ); + } + /** * Assert the total amount of times a notification was sent. * @@ -169,9 +197,7 @@ public function assertSentTimes($notification, $expectedCount) { $actualCount = collect($this->notifications) ->flatten(1) - ->reduce(function ($count, $sent) use ($notification) { - return $count + count($sent[$notification] ?? []); - }, 0); + ->reduce(fn ($count, $sent) => $count + count($sent[$notification] ?? []), 0); PHPUnit::assertSame( $expectedCount, $actualCount, @@ -179,6 +205,22 @@ public function assertSentTimes($notification, $expectedCount) ); } + /** + * Assert the total count of notification that were sent. + * + * @param int $expectedCount + * @return void + */ + public function assertCount($expectedCount) + { + $actualCount = collect($this->notifications)->flatten(3)->count(); + + PHPUnit::assertSame( + $expectedCount, $actualCount, + "Expected {$expectedCount} notifications to be sent, but {$actualCount} were sent." + ); + } + /** * Assert the total amount of times a notification was sent. * @@ -207,15 +249,13 @@ public function sent($notifiable, $notification, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; $notifications = collect($this->notificationsFor($notifiable, $notification)); - return $notifications->filter(function ($arguments) use ($callback) { - return $callback(...array_values($arguments)); - })->pluck('notification'); + return $notifications->filter( + fn ($arguments) => $callback(...array_values($arguments)) + )->pluck('notification'); } /** @@ -278,9 +318,7 @@ public function sendNow($notifiables, $notification, array $channels = null) if (method_exists($notification, 'shouldSend')) { $notifiableChannels = array_filter( $notifiableChannels, - function ($channel) use ($notification, $notifiable) { - return $notification->shouldSend($notifiable, $channel) !== false; - } + fn ($channel) => $notification->shouldSend($notifiable, $channel) !== false ); if (empty($notifiableChannels)) { @@ -324,4 +362,14 @@ public function locale($locale) return $this; } + + /** + * Get the notifications that have been sent. + * + * @return array + */ + public function sentNotifications() + { + return $this->notifications; + } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/PendingBatchFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/PendingBatchFake.php index c60b4b50b..3d0f49929 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/PendingBatchFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/PendingBatchFake.php @@ -36,4 +36,14 @@ public function dispatch() { return $this->bus->recordPendingBatch($this); } + + /** + * Dispatch the batch after the response is sent to the browser. + * + * @return \Illuminate\Bus\Batch + */ + public function dispatchAfterResponse() + { + return $this->bus->recordPendingBatch($this); + } } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/QueueFake.php b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/QueueFake.php index d37cd6723..f2caa768d 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/QueueFake.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Testing/Fakes/QueueFake.php @@ -6,6 +6,7 @@ use Closure; use Illuminate\Contracts\Queue\Queue; use Illuminate\Queue\QueueManager; +use Illuminate\Support\Collection; use Illuminate\Support\Traits\ReflectsClosures; use PHPUnit\Framework\Assert as PHPUnit; @@ -13,6 +14,27 @@ class QueueFake extends QueueManager implements Queue { use ReflectsClosures; + /** + * The original queue manager. + * + * @var \Illuminate\Contracts\Queue\Queue + */ + protected $queue; + + /** + * The job types that should be intercepted instead of pushed to the queue. + * + * @var \Illuminate\Support\Collection + */ + protected $jobsToFake; + + /** + * The job types that should be pushed to the queue and not intercepted. + * + * @var \Illuminate\Support\Collection + */ + protected $jobsToBeQueued; + /** * All of the jobs that have been pushed. * @@ -20,6 +42,36 @@ class QueueFake extends QueueManager implements Queue */ protected $jobs = []; + /** + * Create a new fake queue instance. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @param array $jobsToFake + * @param \Illuminate\Queue\QueueManager|null $queue + * @return void + */ + public function __construct($app, $jobsToFake = [], $queue = null) + { + parent::__construct($app); + + $this->jobsToFake = Collection::wrap($jobsToFake); + $this->jobsToBeQueued = Collection::make(); + $this->queue = $queue; + } + + /** + * Specify the jobs that should be queued instead of faked. + * + * @param array|string $jobsToBeQueued + * @return $this + */ + public function except($jobsToBeQueued) + { + $this->jobsToBeQueued = Collection::wrap($jobsToBeQueued)->merge($this->jobsToBeQueued); + + return $this; + } + /** * Assert if a job was pushed based on a truth-test callback. * @@ -135,14 +187,10 @@ public function assertPushedWithoutChain($job, $callback = null) */ protected function assertPushedWithChainOfObjects($job, $expectedChain, $callback) { - $chain = collect($expectedChain)->map(function ($job) { - return serialize($job); - })->all(); + $chain = collect($expectedChain)->map(fn ($job) => serialize($job))->all(); PHPUnit::assertTrue( - $this->pushed($job, $callback)->filter(function ($job) use ($chain) { - return $job->chained == $chain; - })->isNotEmpty(), + $this->pushed($job, $callback)->filter(fn ($job) => $job->chained == $chain)->isNotEmpty(), 'The expected chain was not pushed.' ); } @@ -178,9 +226,7 @@ protected function assertPushedWithChainOfClasses($job, $expectedChain, $callbac */ protected function isChainOfObjects($chain) { - return ! collect($chain)->contains(function ($job) { - return ! is_object($job); - }); + return ! collect($chain)->contains(fn ($job) => ! is_object($job)); } /** @@ -225,13 +271,11 @@ public function pushed($job, $callback = null) return collect(); } - $callback = $callback ?: function () { - return true; - }; + $callback = $callback ?: fn () => true; - return collect($this->jobs[$job])->filter(function ($data) use ($callback) { - return $callback($data['job'], $data['queue']); - })->pluck('job'); + return collect($this->jobs[$job])->filter( + fn ($data) => $callback($data['job'], $data['queue'], $data['data']) + )->pluck('job'); } /** @@ -264,9 +308,9 @@ public function connection($value = null) */ public function size($queue = null) { - return collect($this->jobs)->flatten(1)->filter(function ($job) use ($queue) { - return $job['queue'] === $queue; - })->count(); + return collect($this->jobs)->flatten(1)->filter( + fn ($job) => $job['queue'] === $queue + )->count(); } /** @@ -279,10 +323,55 @@ public function size($queue = null) */ public function push($job, $data = '', $queue = null) { - $this->jobs[is_object($job) ? get_class($job) : $job][] = [ - 'job' => $job, - 'queue' => $queue, - ]; + if ($this->shouldFakeJob($job)) { + $this->jobs[is_object($job) ? get_class($job) : $job][] = [ + 'job' => $job, + 'queue' => $queue, + 'data' => $data, + ]; + } else { + is_object($job) && isset($job->connection) + ? $this->queue->connection($job->connection)->push($job, $data, $queue) + : $this->queue->push($job, $data, $queue); + } + } + + /** + * Determine if a job should be faked or actually dispatched. + * + * @param object $job + * @return bool + */ + public function shouldFakeJob($job) + { + if ($this->shouldDispatchJob($job)) { + return false; + } + + if ($this->jobsToFake->isEmpty()) { + return true; + } + + return $this->jobsToFake->contains( + fn ($jobToFake) => $job instanceof ((string) $jobToFake) + ); + } + + /** + * Determine if a job should be pushed to the queue instead of faked. + * + * @param object $job + * @return bool + */ + protected function shouldDispatchJob($job) + { + if ($this->jobsToBeQueued->isEmpty()) { + return false; + } + + return $this->jobsToBeQueued->contains( + fn ($jobToQueue) => $job instanceof ((string) $jobToQueue) + ); } /** @@ -299,7 +388,7 @@ public function pushRaw($payload, $queue = null, array $options = []) } /** - * Push a new job onto the queue after a delay. + * Push a new job onto the queue after (n) seconds. * * @param \DateTimeInterface|\DateInterval|int $delay * @param string|object $job @@ -326,7 +415,7 @@ public function pushOn($queue, $job, $data = '') } /** - * Push a new job onto the queue after a delay. + * Push a new job onto a specific queue after (n) seconds. * * @param string $queue * @param \DateTimeInterface|\DateInterval|int $delay diff --git a/lam/lib/3rdParty/composer/illuminate/support/Timebox.php b/lam/lib/3rdParty/composer/illuminate/support/Timebox.php index 32fd607db..6e2aa4dae 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/Timebox.php +++ b/lam/lib/3rdParty/composer/illuminate/support/Timebox.php @@ -14,9 +14,11 @@ class Timebox /** * Invoke the given callback within the specified timebox minimum. * - * @param callable $callback + * @template TCallReturnType + * + * @param (callable($this): TCallReturnType) $callback * @param int $microseconds - * @return mixed + * @return TCallReturnType */ public function call(callable $callback, int $microseconds) { @@ -24,7 +26,7 @@ public function call(callable $callback, int $microseconds) $result = $callback($this); - $remainder = $microseconds - ((microtime(true) - $start) * 1000000); + $remainder = intval($microseconds - ((microtime(true) - $start) * 1000000)); if (! $this->earlyReturn && $remainder > 0) { $this->usleep($remainder); @@ -60,10 +62,10 @@ public function dontReturnEarly() /** * Sleep for the specified number of microseconds. * - * @param $microseconds + * @param int $microseconds * @return void */ - protected function usleep($microseconds) + protected function usleep(int $microseconds) { usleep($microseconds); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/Traits/Conditionable.php b/lam/lib/3rdParty/composer/illuminate/support/Traits/Conditionable.php deleted file mode 100644 index 798082794..000000000 --- a/lam/lib/3rdParty/composer/illuminate/support/Traits/Conditionable.php +++ /dev/null @@ -1,44 +0,0 @@ -input = $input; } + /** + * Determine if the validated input has one or more keys. + * + * @param mixed $keys + * @return bool + */ + public function has($keys) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + foreach ($keys as $key) { + if (! Arr::has($this->input, $key)) { + return false; + } + } + + return true; + } + + /** + * Determine if the validated input is missing one or more keys. + * + * @param mixed $keys + * @return bool + */ + public function missing($keys) + { + return ! $this->has($keys); + } + /** * Get a subset containing the provided keys with values from the input data. * - * @param array|mixed $keys + * @param mixed $keys * @return array */ public function only($keys) @@ -54,7 +85,7 @@ public function only($keys) /** * Get all of the input except for a specified array of items. * - * @param array|mixed $keys + * @param mixed $keys * @return array */ public function except($keys) @@ -159,8 +190,7 @@ public function __unset($name) * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return isset($this->input[$key]); } @@ -171,8 +201,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->input[$key]; } @@ -184,8 +213,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { if (is_null($key)) { $this->input[] = $value; @@ -200,8 +228,7 @@ public function offsetSet($key, $value) * @param string $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { unset($this->input[$key]); } @@ -211,8 +238,7 @@ public function offsetUnset($key) * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->input); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/ViewErrorBag.php b/lam/lib/3rdParty/composer/illuminate/support/ViewErrorBag.php index d51bb534d..ff9da4fc5 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/ViewErrorBag.php +++ b/lam/lib/3rdParty/composer/illuminate/support/ViewErrorBag.php @@ -78,8 +78,7 @@ public function any() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->getBag('default')->count(); } diff --git a/lam/lib/3rdParty/composer/illuminate/support/composer.json b/lam/lib/3rdParty/composer/illuminate/support/composer.json index 527bdcbb8..61b01cfe2 100644 --- a/lam/lib/3rdParty/composer/illuminate/support/composer.json +++ b/lam/lib/3rdParty/composer/illuminate/support/composer.json @@ -14,15 +14,17 @@ } ], "require": { - "php": "^7.3|^8.0", - "ext-json": "*", + "php": "^8.0.2", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "doctrine/inflector": "^1.4|^2.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.53.1", - "voku/portable-ascii": "^1.6.1" + "doctrine/inflector": "^2.0", + "illuminate/collections": "^9.0", + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "nesbot/carbon": "^2.62.1", + "voku/portable-ascii": "^2.0" }, "conflict": { "tightenco/collect": "<5.5.33" @@ -37,15 +39,16 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "9.x-dev" } }, "suggest": { - "illuminate/filesystem": "Required to use the composer class (^8.0).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", - "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", - "symfony/process": "Required to use the composer class (^5.4).", - "symfony/var-dumper": "Required to use the dd function (^5.4).", + "illuminate/filesystem": "Required to use the composer class (^9.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^6.0).", + "symfony/uid": "Required to use Str::ulid() (^6.0).", + "symfony/var-dumper": "Required to use the dd function (^6.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, "config": { diff --git a/lam/lib/3rdParty/composer/illuminate/support/helpers.php b/lam/lib/3rdParty/composer/illuminate/support/helpers.php index 0b82fe769..bb8d178f4 100755 --- a/lam/lib/3rdParty/composer/illuminate/support/helpers.php +++ b/lam/lib/3rdParty/composer/illuminate/support/helpers.php @@ -6,6 +6,7 @@ use Illuminate\Support\Env; use Illuminate\Support\HigherOrderTapProxy; use Illuminate\Support\Optional; +use Illuminate\Support\Str; if (! function_exists('append_config')) { /** @@ -101,7 +102,7 @@ function class_uses_recursive($class) /** * Encode HTML special characters in a string. * - * @param \Illuminate\Contracts\Support\DeferringDisplayableValue|\Illuminate\Contracts\Support\Htmlable|string|null $value + * @param \Illuminate\Contracts\Support\DeferringDisplayableValue|\Illuminate\Contracts\Support\Htmlable|\BackedEnum|string|null $value * @param bool $doubleEncode * @return string */ @@ -115,6 +116,10 @@ function e($value, $doubleEncode = true) return $value->toHtml(); } + if ($value instanceof BackedEnum) { + $value = $value->value; + } + return htmlspecialchars($value ?? '', ENT_QUOTES, 'UTF-8', $doubleEncode); } } @@ -203,7 +208,7 @@ function optional($value = null, callable $callback = null) function preg_replace_array($pattern, array $replacements, $subject) { return preg_replace_callback($pattern, function () use (&$replacements) { - foreach ($replacements as $key => $value) { + foreach ($replacements as $value) { return array_shift($replacements); } }, $subject); @@ -214,7 +219,7 @@ function preg_replace_array($pattern, array $replacements, $subject) /** * Retry an operation a given number of times. * - * @param int $times + * @param int|array $times * @param callable $callback * @param int|\Closure $sleepMilliseconds * @param callable|null $when @@ -226,6 +231,14 @@ function retry($times, callable $callback, $sleepMilliseconds = 0, $when = null) { $attempts = 0; + $backoff = []; + + if (is_array($times)) { + $backoff = $times; + + $times = count($times) + 1; + } + beginning: $attempts++; $times--; @@ -237,8 +250,10 @@ function retry($times, callable $callback, $sleepMilliseconds = 0, $when = null) throw $e; } + $sleepMilliseconds = $backoff[$attempts - 1] ?? $sleepMilliseconds; + if ($sleepMilliseconds) { - usleep(value($sleepMilliseconds, $attempts) * 1000); + usleep(value($sleepMilliseconds, $attempts, $e) * 1000); } goto beginning; @@ -246,6 +261,34 @@ function retry($times, callable $callback, $sleepMilliseconds = 0, $when = null) } } +if (! function_exists('str')) { + /** + * Get a new stringable object from the given string. + * + * @param string|null $string + * @return \Illuminate\Support\Stringable|mixed + */ + function str($string = null) + { + if (func_num_args() === 0) { + return new class + { + public function __call($method, $parameters) + { + return Str::$method(...$parameters); + } + + public function __toString() + { + return ''; + } + }; + } + + return Str::of($string); + } +} + if (! function_exists('tap')) { /** * Call the given Closure with the given value then return the value. @@ -368,9 +411,12 @@ function windows_os() /** * Return the given value, optionally passed through the given callback. * - * @param mixed $value - * @param callable|null $callback - * @return mixed + * @template TValue + * @template TReturn + * + * @param TValue $value + * @param (callable(TValue): (TReturn))|null $callback + * @return ($callback is null ? TValue : TReturn) */ function with($value, callable $callback = null) { diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/readme.md b/lam/lib/3rdParty/composer/nesbot/carbon/readme.md index 057327a5c..b8ec4bf84 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/readme.md +++ b/lam/lib/3rdParty/composer/nesbot/carbon/readme.md @@ -124,9 +124,10 @@ Support this project by becoming a sponsor. Your logo will show up here with a l Casino-portugal.pt Slots City Probukmacher -Игровые автоматы +Игровые автоматы inkedin Онлайн казино України +Chudovo AzuraCast Triplebyte GitHub Sponsors diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonInterval.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonInterval.php index 9eb49c028..8437c545e 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonInterval.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonInterval.php @@ -15,6 +15,7 @@ use Carbon\Exceptions\BadFluentSetterException; use Carbon\Exceptions\InvalidCastException; use Carbon\Exceptions\InvalidIntervalException; +use Carbon\Exceptions\OutOfRangeException; use Carbon\Exceptions\ParseErrorException; use Carbon\Exceptions\UnitNotConfiguredException; use Carbon\Exceptions\UnknownGetterException; @@ -32,8 +33,10 @@ use DateTimeInterface; use DateTimeZone; use Exception; +use InvalidArgumentException; use ReflectionException; use ReturnTypeWillChange; +use RuntimeException; use Throwable; /** @@ -246,6 +249,11 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface */ private static $flipCascadeFactors; + /** + * @var bool + */ + private static $floatSettersEnabled = false; + /** * The registered macros. * @@ -347,6 +355,19 @@ public static function setCascadeFactors(array $cascadeFactors) static::$cascadeFactors = $cascadeFactors; } + /** + * This option allow you to opt-in for the Carbon 3 behavior where float + * values will no longer be cast to integer (so truncated). + * + * ⚠️ This settings will be applied globally, which mean your whole application + * code including the third-party dependencies that also may use Carbon will + * adopt the new behavior. + */ + public static function enableFloatSetters(bool $floatSettersEnabled = true): void + { + self::$floatSettersEnabled = $floatSettersEnabled; + } + /////////////////////////////////////////////////////////////////// //////////////////////////// CONSTRUCTORS ///////////////////////// /////////////////////////////////////////////////////////////////// @@ -355,13 +376,13 @@ public static function setCascadeFactors(array $cascadeFactors) * Create a new CarbonInterval instance. * * @param Closure|DateInterval|string|int|null $years - * @param int|null $months - * @param int|null $weeks - * @param int|null $days - * @param int|null $hours - * @param int|null $minutes - * @param int|null $seconds - * @param int|null $microseconds + * @param int|float|null $months + * @param int|float|null $weeks + * @param int|float|null $days + * @param int|float|null $hours + * @param int|float|null $minutes + * @param int|float|null $seconds + * @param int|float|null $microseconds * * @throws Exception when the interval_spec (passed as $years) cannot be parsed as an interval. */ @@ -381,8 +402,9 @@ public function __construct($years = 1, $months = null, $weeks = null, $days = n } $spec = $years; + $isStringSpec = (\is_string($spec) && !preg_match('/^[\d.]/', $spec)); - if (!\is_string($spec) || (float) $years || preg_match('/^[\d.]/', $years)) { + if (!$isStringSpec || (float) $years) { $spec = static::PERIOD_PREFIX; $spec .= $years > 0 ? $years.static::PERIOD_YEARS : ''; @@ -407,7 +429,74 @@ public function __construct($years = 1, $months = null, $weeks = null, $days = n } } - parent::__construct($spec); + try { + parent::__construct($spec); + } catch (Throwable $exception) { + try { + parent::__construct('PT0S'); + + if ($isStringSpec) { + if (!preg_match('/^P + (?:(?[+-]?\d*(?:\.\d+)?)Y)? + (?:(?[+-]?\d*(?:\.\d+)?)M)? + (?:(?[+-]?\d*(?:\.\d+)?)W)? + (?:(?[+-]?\d*(?:\.\d+)?)D)? + (?:T + (?:(?[+-]?\d*(?:\.\d+)?)H)? + (?:(?[+-]?\d*(?:\.\d+)?)M)? + (?:(?[+-]?\d*(?:\.\d+)?)S)? + )? + $/x', $spec, $match)) { + throw new InvalidArgumentException("Invalid duration: $spec"); + } + + $years = (float) ($match['year'] ?? 0); + $this->assertSafeForInteger('year', $years); + $months = (float) ($match['month'] ?? 0); + $this->assertSafeForInteger('month', $months); + $weeks = (float) ($match['week'] ?? 0); + $this->assertSafeForInteger('week', $weeks); + $days = (float) ($match['day'] ?? 0); + $this->assertSafeForInteger('day', $days); + $hours = (float) ($match['hour'] ?? 0); + $this->assertSafeForInteger('hour', $hours); + $minutes = (float) ($match['minute'] ?? 0); + $this->assertSafeForInteger('minute', $minutes); + $seconds = (float) ($match['second'] ?? 0); + $this->assertSafeForInteger('second', $seconds); + } + + $totalDays = (($weeks * static::getDaysPerWeek()) + $days); + $this->assertSafeForInteger('days total (including weeks)', $totalDays); + + $this->y = (int) $years; + $this->m = (int) $months; + $this->d = (int) $totalDays; + $this->h = (int) $hours; + $this->i = (int) $minutes; + $this->s = (int) $seconds; + + if ( + ((float) $this->y) !== $years || + ((float) $this->m) !== $months || + ((float) $this->d) !== $totalDays || + ((float) $this->h) !== $hours || + ((float) $this->i) !== $minutes || + ((float) $this->s) !== $seconds + ) { + $this->add(static::fromString( + ($years - $this->y).' years '. + ($months - $this->m).' months '. + ($totalDays - $this->d).' days '. + ($hours - $this->h).' hours '. + ($minutes - $this->i).' minutes '. + ($seconds - $this->s).' seconds ' + )); + } + } catch (Throwable $secondException) { + throw $secondException instanceof OutOfRangeException ? $secondException : $exception; + } + } if ($microseconds !== null) { $this->f = $microseconds / Carbon::MICROSECONDS_PER_SECOND; @@ -683,6 +772,23 @@ public static function __callStatic($method, $parameters) } } + /** + * Evaluate the PHP generated by var_export() and recreate the exported CarbonInterval instance. + * + * @param array $dump data as exported by var_export() + * + * @return static + */ + #[ReturnTypeWillChange] + public static function __set_state($dump) + { + /** @noinspection PhpVoidFunctionResultUsedInspection */ + /** @var DateInterval $dateInterval */ + $dateInterval = parent::__set_state($dump); + + return static::instance($dateInterval); + } + /** * Return the current context from inside a macro callee or a new one if static. * @@ -953,11 +1059,18 @@ public function cast(string $className) * set the $days field. * * @param DateInterval $interval + * @param bool $skipCopy set to true to return the passed object + * (without copying it) if it's already of the + * current class * * @return static */ - public static function instance(DateInterval $interval, array $skip = []) + public static function instance(DateInterval $interval, array $skip = [], bool $skipCopy = false) { + if ($skipCopy && $interval instanceof static) { + return $interval; + } + return self::castIntervalToClass($interval, static::class, $skip); } @@ -969,17 +1082,20 @@ public static function instance(DateInterval $interval, array $skip = []) * * @param mixed|int|DateInterval|string|Closure|null $interval interval or number of the given $unit * @param string|null $unit if specified, $interval must be an integer + * @param bool $skipCopy set to true to return the passed object + * (without copying it) if it's already of the + * current class * * @return static|null */ - public static function make($interval, $unit = null) + public static function make($interval, $unit = null, bool $skipCopy = false) { if ($unit) { $interval = "$interval ".Carbon::pluralUnit($unit); } if ($interval instanceof DateInterval) { - return static::instance($interval); + return static::instance($interval, [], $skipCopy); } if ($interval instanceof Closure) { @@ -1145,43 +1261,63 @@ public function set($name, $value = null) foreach ($properties as $key => $value) { switch (Carbon::singularUnit(rtrim($key, 'z'))) { case 'year': + $this->checkIntegerValue($key, $value); $this->y = $value; + $this->handleDecimalPart('year', $value, $this->y); break; case 'month': + $this->checkIntegerValue($key, $value); $this->m = $value; + $this->handleDecimalPart('month', $value, $this->m); break; case 'week': - $this->d = $value * (int) static::getDaysPerWeek(); + $this->checkIntegerValue($key, $value); + $days = $value * (int) static::getDaysPerWeek(); + $this->assertSafeForInteger('days total (including weeks)', $days); + $this->d = $days; + $this->handleDecimalPart('day', $days, $this->d); break; case 'day': + $this->checkIntegerValue($key, $value); $this->d = $value; + $this->handleDecimalPart('day', $value, $this->d); break; case 'daysexcludeweek': case 'dayzexcludeweek': - $this->d = $this->weeks * (int) static::getDaysPerWeek() + $value; + $this->checkIntegerValue($key, $value); + $days = $this->weeks * (int) static::getDaysPerWeek() + $value; + $this->assertSafeForInteger('days total (including weeks)', $days); + $this->d = $days; + $this->handleDecimalPart('day', $days, $this->d); break; case 'hour': + $this->checkIntegerValue($key, $value); $this->h = $value; + $this->handleDecimalPart('hour', $value, $this->h); break; case 'minute': + $this->checkIntegerValue($key, $value); $this->i = $value; + $this->handleDecimalPart('minute', $value, $this->i); break; case 'second': + $this->checkIntegerValue($key, $value); $this->s = $value; + $this->handleDecimalPart('second', $value, $this->s); break; @@ -2841,4 +2977,78 @@ private function needsDeclension(string $mode, int $index, int $parts): bool return true; } } + + private function checkIntegerValue(string $name, $value) + { + if (\is_int($value)) { + return; + } + + $this->assertSafeForInteger($name, $value); + + if (\is_float($value) && (((float) (int) $value) === $value)) { + return; + } + + if (!self::$floatSettersEnabled) { + $type = \gettype($value); + @trigger_error( + "Since 2.70.0, it's deprecated to pass $type value for $name.\n". + "It's truncated when stored as an integer interval unit.\n". + "From 3.0.0, decimal part will no longer be truncated and will be cascaded to smaller units.\n". + "- To maintain the current behavior, use explicit cast: $name((int) \$value)\n". + "- To adopt the new behavior globally, call CarbonInterval::enableFloatSetters()\n", + \E_USER_DEPRECATED + ); + } + } + + /** + * Throw an exception if precision loss when storing the given value as an integer would be >= 1.0. + */ + private function assertSafeForInteger(string $name, $value) + { + if ($value && !\is_int($value) && ($value >= 0x7fffffffffffffff || $value <= -0x7fffffffffffffff)) { + throw new OutOfRangeException($name, -0x7fffffffffffffff, 0x7fffffffffffffff, $value); + } + } + + private function handleDecimalPart(string $unit, $value, $integerValue) + { + if (self::$floatSettersEnabled) { + $floatValue = (float) $value; + $base = (float) $integerValue; + + if ($floatValue === $base) { + return; + } + + $units = [ + 'y' => 'year', + 'm' => 'month', + 'd' => 'day', + 'h' => 'hour', + 'i' => 'minute', + 's' => 'second', + ]; + $upper = true; + + foreach ($units as $property => $name) { + if ($name === $unit) { + $upper = false; + + continue; + } + + if (!$upper && $this->$property !== 0) { + throw new RuntimeException( + "You cannot set $unit to a float value as $name would be overridden, ". + 'set it first to 0 explicitly if you really want to erase its value' + ); + } + } + + $this->add($unit, $floatValue - $base); + } + } } diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonPeriod.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonPeriod.php index 9ddcf61ab..9633d2b8e 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonPeriod.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/CarbonPeriod.php @@ -88,6 +88,10 @@ * @method static static minute($minutes = 1) Alias for minutes(). * @method static static seconds($seconds = 1) Create instance specifying a number of seconds for date interval or replace the interval by the given a number of seconds if called on an instance. * @method static static second($seconds = 1) Alias for seconds(). + * @method static static milliseconds($milliseconds = 1) Create instance specifying a number of milliseconds for date interval or replace the interval by the given a number of milliseconds if called on an instance. + * @method static static millisecond($milliseconds = 1) Alias for milliseconds(). + * @method static static microseconds($microseconds = 1) Create instance specifying a number of microseconds for date interval or replace the interval by the given a number of microseconds if called on an instance. + * @method static static microsecond($microseconds = 1) Alias for microseconds(). * @method $this roundYear(float $precision = 1, string $function = "round") Round the current instance year with given precision using the given function. * @method $this roundYears(float $precision = 1, string $function = "round") Round the current instance year with given precision using the given function. * @method $this floorYear(float $precision = 1) Truncate the current instance year with given precision. @@ -663,6 +667,8 @@ public function __construct(...$arguments) } } + $optionsSet = false; + foreach ($arguments as $argument) { $parsedDate = null; @@ -686,8 +692,9 @@ public function __construct(...$arguments) $this->setEndDate($parsedDate); } elseif ($this->recurrences === null && $this->endDate === null && is_numeric($argument)) { $this->setRecurrences($argument); - } elseif ($this->options === null && (\is_int($argument) || $argument === null)) { - $this->setOptions($argument); + } elseif (!$optionsSet && (\is_int($argument) || $argument === null)) { + $optionsSet = true; + $this->setOptions(((int) $this->options) | ((int) $argument)); } else { throw new InvalidPeriodParameterException('Invalid constructor parameters.'); } @@ -1809,6 +1816,10 @@ public function __call($method, $parameters) case 'minute': case 'seconds': case 'second': + case 'milliseconds': + case 'millisecond': + case 'microseconds': + case 'microsecond': return $this->setDateInterval(( // Override default P1D when instantiating via fluent setters. [$this->isDefaultInterval ? new CarbonInterval('PT0S') : $this->dateInterval, $method] diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/MessageFormatter/MessageFormatterMapper.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/MessageFormatter/MessageFormatterMapper.php index a230b0631..c05480876 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/MessageFormatter/MessageFormatterMapper.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/MessageFormatter/MessageFormatterMapper.php @@ -15,11 +15,13 @@ use Symfony\Component\Translation\Formatter\MessageFormatter; use Symfony\Component\Translation\Formatter\MessageFormatterInterface; +// @codeCoverageIgnoreStart $transMethod = new ReflectionMethod(MessageFormatterInterface::class, 'format'); require $transMethod->getParameters()[0]->hasType() ? __DIR__.'/../../../lazy/Carbon/MessageFormatter/MessageFormatterMapperStrongType.php' : __DIR__.'/../../../lazy/Carbon/MessageFormatter/MessageFormatterMapperWeakType.php'; +// @codeCoverageIgnoreEnd final class MessageFormatterMapper extends LazyMessageFormatter { diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Date.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Date.php index da3775c21..8ae5c1781 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Date.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Date.php @@ -2310,6 +2310,7 @@ public static function getFormatsToIsoReplacements() 'c' => true, 'r' => true, 'U' => true, + 'T' => true, ]; } diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/IntervalRounding.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/IntervalRounding.php index 4cd66b676..f069c280d 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/IntervalRounding.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/IntervalRounding.php @@ -40,7 +40,7 @@ protected function roundWith($precision, $function) $unit = 'second'; if ($precision instanceof DateInterval) { - $precision = (string) CarbonInterval::instance($precision); + $precision = (string) CarbonInterval::instance($precision, [], true); } if (\is_string($precision) && preg_match('/^\s*(?\d+)?\s*(?\w+)(?\W.*)?$/', $precision, $match)) { diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Localization.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Localization.php index ff249566f..46aff113e 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Localization.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Localization.php @@ -23,6 +23,7 @@ use Symfony\Contracts\Translation\LocaleAwareInterface; use Symfony\Contracts\Translation\TranslatorInterface as ContractsTranslatorInterface; +// @codeCoverageIgnoreStart if (interface_exists('Symfony\\Contracts\\Translation\\TranslatorInterface') && !interface_exists('Symfony\\Component\\Translation\\TranslatorInterface') ) { @@ -31,6 +32,7 @@ class_alias( 'Symfony\\Component\\Translation\\TranslatorInterface' ); } +// @codeCoverageIgnoreEnd /** * Trait Localization. diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Serialization.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Serialization.php index 53fead69e..c1d5c5e13 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Serialization.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Serialization.php @@ -146,7 +146,7 @@ public function __sleep() public function __serialize(): array { // @codeCoverageIgnoreStart - if (isset($this->timezone_type)) { + if (isset($this->timezone_type, $this->timezone, $this->date)) { return [ 'date' => $this->date ?? null, 'timezone_type' => $this->timezone_type, diff --git a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Units.php b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Units.php index 7aadd65bd..5be14ec7e 100644 --- a/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Units.php +++ b/lam/lib/3rdParty/composer/nesbot/carbon/src/Carbon/Traits/Units.php @@ -198,7 +198,7 @@ public function rawAdd(DateInterval $interval) public function add($unit, $value = 1, $overflow = null) { if (\is_string($unit) && \func_num_args() === 1) { - $unit = CarbonInterval::make($unit); + $unit = CarbonInterval::make($unit, [], true); } if ($unit instanceof CarbonConverterInterface) { @@ -368,7 +368,7 @@ public function rawSub(DateInterval $interval) public function sub($unit, $value = 1, $overflow = null) { if (\is_string($unit) && \func_num_args() === 1) { - $unit = CarbonInterval::make($unit); + $unit = CarbonInterval::make($unit, [], true); } if ($unit instanceof CarbonConverterInterface) { @@ -404,7 +404,7 @@ public function sub($unit, $value = 1, $overflow = null) public function subtract($unit, $value = 1, $overflow = null) { if (\is_string($unit) && \func_num_args() === 1) { - $unit = CarbonInterval::make($unit); + $unit = CarbonInterval::make($unit, [], true); } return $this->sub($unit, $value, $overflow); diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/README.md b/lam/lib/3rdParty/composer/phpseclib/phpseclib/README.md index 64c06ba28..bbb1e9f06 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/README.md +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/README.md @@ -51,8 +51,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / * PHP4 compatible * Composer compatible (PSR-0 autoloading) * Install using Composer: `composer require phpseclib/phpseclib:~1.0` -* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm) -* [Download 1.0.20 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.20.zip/download) +* [Download 1.0.21 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.21.zip/download) ## Security contact information diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php index 407f03699..256c86906 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -130,7 +130,7 @@ protected static function initialize_static_variables() * * @param string $key * @param string $password optional - * @return AsymmetricKey + * @return \phpseclib3\Crypt\Common\PublicKey|\phpseclib3\Crypt\Common\PrivateKey */ public static function load($key, $password = false) { diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/File/ASN1.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/File/ASN1.php index cf23dd732..3096ff1a1 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -1402,7 +1402,7 @@ public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self:: return false; } break; - case ($c & 0x80000000) != 0: + case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: return false; case $c >= 0x04000000: $v .= chr(0x80 | ($c & 0x3F)); diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger.php index 3524668e1..c6609e4d5 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -136,7 +136,7 @@ private static function initialize_static_variables() { if (!isset(self::$mainEngine)) { $engines = [ - ['GMP'], + ['GMP', ['DefaultEngine']], ['PHP64', ['OpenSSL']], ['BCMath', ['OpenSSL']], ['PHP32', ['OpenSSL']], @@ -145,7 +145,7 @@ private static function initialize_static_variables() ]; foreach ($engines as $engine) { try { - self::setEngine($engine[0], isset($engine[1]) ? $engine[1] : []); + self::setEngine($engine[0], $engine[1]); break; } catch (\Exception $e) { } diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php index 964cd170d..18f78cdb7 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -80,10 +80,10 @@ protected function initialize($base) } $step = count($vals) & 3; if ($step) { - $digit = floor($digit / pow(2, 2 * $step)); + $digit = (int) floor($digit / pow(2, 2 * $step)); } if ($step != 3) { - $digit &= static::MAX_DIGIT; + $digit = (int) fmod($digit, static::BASE_FULL); $i++; } $vals[] = $digit; diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php index 748f9a49f..ddb04912d 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -312,8 +312,11 @@ public function negate() */ public function toBytes() { - $length = static::$modulo[$this->instanceID]->getLengthInBytes(); - return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + if (isset(static::$modulo[$this->instanceID])) { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + } + return $this->value->toBytes(); } /** diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Net/SFTP.php index fb136bd70..cdf0bec69 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -2489,14 +2489,6 @@ public function get($remote_file, $local_file = false, $offset = 0, $length = -1 } } - if ($length > 0 && $length <= $offset - $start) { - if ($local_file === false) { - $content = substr($content, 0, $length); - } else { - ftruncate($fp, $length + $res_offset); - } - } - if ($fclose_check) { fclose($fp); diff --git a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/bootstrap.php b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/bootstrap.php index 517106c3a..b794d5497 100644 --- a/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/bootstrap.php +++ b/lam/lib/3rdParty/composer/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -20,3 +20,13 @@ ); } } + +// see https://github.com/php/php-src/issues/11917 +if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && !defined('PHPSECLIB_ALLOW_JIT')) { + $status = opcache_get_status(); + if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { + throw new UnexpectedValueException( + 'JIT on Windows is not currently supported' + ); + } +} diff --git a/lam/lib/3rdParty/composer/psr/container/composer.json b/lam/lib/3rdParty/composer/psr/container/composer.json index 017f41ea6..baf6cd1a0 100644 --- a/lam/lib/3rdParty/composer/psr/container/composer.json +++ b/lam/lib/3rdParty/composer/psr/container/composer.json @@ -18,5 +18,10 @@ "psr-4": { "Psr\\Container\\": "src/" } + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } } } diff --git a/lam/lib/3rdParty/composer/psr/container/src/ContainerInterface.php b/lam/lib/3rdParty/composer/psr/container/src/ContainerInterface.php index cf8e7fd33..b2cad4015 100644 --- a/lam/lib/3rdParty/composer/psr/container/src/ContainerInterface.php +++ b/lam/lib/3rdParty/composer/psr/container/src/ContainerInterface.php @@ -32,5 +32,5 @@ public function get(string $id); * * @return bool */ - public function has(string $id); + public function has(string $id): bool; } diff --git a/lam/lib/3rdParty/composer/psr/http-client/CHANGELOG.md b/lam/lib/3rdParty/composer/psr/http-client/CHANGELOG.md index e2dc25f51..babba7c7b 100644 --- a/lam/lib/3rdParty/composer/psr/http-client/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/psr/http-client/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 1.0.3 + +Add `source` link in composer.json. No code changes. + +## 1.0.2 + +Allow PSR-7 (psr/http-message) 2.0. No code changes. + ## 1.0.1 Allow installation with PHP 8. No code changes. diff --git a/lam/lib/3rdParty/composer/psr/http-client/composer.json b/lam/lib/3rdParty/composer/psr/http-client/composer.json index e4cab2f3e..6fed350be 100644 --- a/lam/lib/3rdParty/composer/psr/http-client/composer.json +++ b/lam/lib/3rdParty/composer/psr/http-client/composer.json @@ -10,6 +10,9 @@ "homepage": "https://www.php-fig.org/" } ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, "require": { "php": "^7.0 || ^8.0", "psr/http-message": "^1.0 || ^2.0" diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/LICENSE b/lam/lib/3rdParty/composer/ramsey/uuid/LICENSE index 5e06cf43b..5b2acc5b7 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/LICENSE +++ b/lam/lib/3rdParty/composer/ramsey/uuid/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2021 Ben Ramsey +Copyright (c) 2012-2023 Ben Ramsey 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/lam/lib/3rdParty/composer/ramsey/uuid/README.md b/lam/lib/3rdParty/composer/ramsey/uuid/README.md index 97e81a501..0db814959 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/README.md +++ b/lam/lib/3rdParty/composer/ramsey/uuid/README.md @@ -8,9 +8,9 @@ Source Code Download Package PHP Programming Language - Read License - Build Status - Codecov Code Coverage + Read License + Build Status + Codecov Code Coverage Psalm Type Coverage

@@ -38,7 +38,7 @@ composer require ramsey/uuid See the documentation for a thorough upgrade guide: -* [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/latest/upgrading/3-to-4.html) +* [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/stable/upgrading/3-to-4.html) ## Documentation @@ -74,10 +74,10 @@ licensed for use under the MIT License (MIT). Please see [LICENSE][] for more information. [rfc4122]: http://tools.ietf.org/html/rfc4122 -[conduct]: https://github.com/ramsey/uuid/blob/main/CODE_OF_CONDUCT.md +[conduct]: https://github.com/ramsey/uuid/blob/4.x/CODE_OF_CONDUCT.md [javauuid]: http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html [pyuuid]: http://docs.python.org/3/library/uuid.html [composer]: http://getcomposer.org/ -[contributing.md]: https://github.com/ramsey/uuid/blob/main/CONTRIBUTING.md -[security.md]: https://github.com/ramsey/uuid/blob/main/SECURITY.md -[license]: https://github.com/ramsey/uuid/blob/main/LICENSE +[contributing.md]: https://github.com/ramsey/uuid/blob/4.x/CONTRIBUTING.md +[security.md]: https://github.com/ramsey/uuid/blob/4.x/SECURITY.md +[license]: https://github.com/ramsey/uuid/blob/4.x/LICENSE diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/composer.json b/lam/lib/3rdParty/composer/ramsey/uuid/composer.json index 3f3b5ac42..9ea4e06b3 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/composer.json +++ b/lam/lib/3rdParty/composer/ramsey/uuid/composer.json @@ -1,23 +1,18 @@ { "name": "ramsey/uuid", - "type": "library", "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "license": "MIT", + "type": "library", "keywords": [ "uuid", "identifier", "guid" ], - "license": "MIT", "require": { - "php": "^7.2 || ^8.0", + "php": "^8.0", "ext-json": "*", - "brick/math": "^0.8 || ^0.9", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" - }, - "replace": { - "rhumsaa/uuid": "self.version" + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ramsey/collection": "^1.2 || ^2.0" }, "require-dev": { "captainhook/captainhook": "^5.10", @@ -26,40 +21,33 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, + "replace": { + "rhumsaa/uuid": "self.version" + }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, - "captainhook": { - "force-install": true - } - }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "psr-4": { "Ramsey\\Uuid\\": "src/" @@ -75,8 +63,21 @@ "Ramsey\\Uuid\\Test\\": "tests/" } }, - "minimum-stability": "dev", - "prefer-stable": true, + "config": { + "allow-plugins": { + "captainhook/plugin-composer": true, + "ergebnis/composer-normalize": true, + "phpstan/extension-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "ramsey/composer-repl": true + }, + "sort-packages": true + }, + "extra": { + "captainhook": { + "force-install": true + } + }, "scripts": { "analyze": [ "@phpstan", @@ -89,8 +90,8 @@ "phpcbf": "phpcbf -vpw --cache=build/cache/phpcs.cache", "phpcs": "phpcs --cache=build/cache/phpcs.cache", "phpstan": [ - "phpstan analyse --no-progress", - "phpstan analyse -c phpstan-tests.neon --no-progress" + "phpstan analyse --no-progress --memory-limit=1G", + "phpstan analyse -c phpstan-tests.neon --no-progress --memory-limit=1G" ], "phpunit": "phpunit --verbose --colors=always", "phpunit-coverage": "phpunit --verbose --colors=always --coverage-html build/coverage", diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/BuilderCollection.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/BuilderCollection.php index 89fa1e3c8..9df3110fd 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/BuilderCollection.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/BuilderCollection.php @@ -27,6 +27,11 @@ /** * A collection of UuidBuilderInterface objects * + * @deprecated this class has been deprecated, and will be removed in 5.0.0. The use-case for this class comes from + * a pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced + * at runtime: that is no longer necessary, now that you can safely verify your code to be correct, and use + * more generic types like `iterable` instead. + * * @extends AbstractCollection */ class BuilderCollection extends AbstractCollection diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/DegradedUuidBuilder.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/DegradedUuidBuilder.php index 23931e416..20b384212 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/DegradedUuidBuilder.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/DegradedUuidBuilder.php @@ -30,15 +30,7 @@ */ class DegradedUuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private TimeConverterInterface $timeConverter; /** * @param NumberConverterInterface $numberConverter The number converter to @@ -47,10 +39,9 @@ class DegradedUuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, + private NumberConverterInterface $numberConverter, ?TimeConverterInterface $timeConverter = null ) { - $this->numberConverter = $numberConverter; $this->timeConverter = $timeConverter ?: new DegradedTimeConverter(); } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/FallbackBuilder.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/FallbackBuilder.php index 470d2f755..ba5f31fbe 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/FallbackBuilder.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Builder/FallbackBuilder.php @@ -28,16 +28,10 @@ class FallbackBuilder implements UuidBuilderInterface { /** - * @var BuilderCollection + * @param iterable $builders An array of UUID builders */ - private $builders; - - /** - * @param BuilderCollection $builders An array of UUID builders - */ - public function __construct(BuilderCollection $builders) + public function __construct(private iterable $builders) { - $this->builders = $builders; } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/GuidStringCodec.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/GuidStringCodec.php index f11e9d50a..04872e0bc 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/GuidStringCodec.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/GuidStringCodec.php @@ -18,6 +18,7 @@ use Ramsey\Uuid\UuidInterface; use function bin2hex; +use function sprintf; use function substr; /** @@ -29,6 +30,26 @@ */ class GuidStringCodec extends StringCodec { + public function encode(UuidInterface $uuid): string + { + $hex = bin2hex($uuid->getFields()->getBytes()); + + /** @var non-empty-string */ + return sprintf( + '%02s%02s%02s%02s-%02s%02s-%02s%02s-%04s-%012s', + substr($hex, 6, 2), + substr($hex, 4, 2), + substr($hex, 2, 2), + substr($hex, 0, 2), + substr($hex, 10, 2), + substr($hex, 8, 2), + substr($hex, 14, 2), + substr($hex, 12, 2), + substr($hex, 16, 4), + substr($hex, 20), + ); + } + public function decode(string $encodedUuid): UuidInterface { $bytes = $this->getBytes($encodedUuid); diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/StringCodec.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/StringCodec.php index 58c9f5806..95f38d2e8 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/StringCodec.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Codec/StringCodec.php @@ -17,12 +17,13 @@ use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use function bin2hex; use function hex2bin; use function implode; +use function sprintf; use function str_replace; use function strlen; use function substr; @@ -36,36 +37,28 @@ */ class StringCodec implements CodecInterface { - /** - * @var UuidBuilderInterface - */ - private $builder; - /** * Constructs a StringCodec * * @param UuidBuilderInterface $builder The builder to use when encoding UUIDs */ - public function __construct(UuidBuilderInterface $builder) + public function __construct(private UuidBuilderInterface $builder) { - $this->builder = $builder; } public function encode(UuidInterface $uuid): string { - /** @var FieldsInterface $fields */ - $fields = $uuid->getFields(); - - return $fields->getTimeLow()->toString() - . '-' - . $fields->getTimeMid()->toString() - . '-' - . $fields->getTimeHiAndVersion()->toString() - . '-' - . $fields->getClockSeqHiAndReserved()->toString() - . $fields->getClockSeqLow()->toString() - . '-' - . $fields->getNode()->toString(); + $hex = bin2hex($uuid->getFields()->getBytes()); + + /** @var non-empty-string */ + return sprintf( + '%08s-%04s-%04s-%04s-%012s', + substr($hex, 0, 8), + substr($hex, 8, 4), + substr($hex, 12, 4), + substr($hex, 16, 4), + substr($hex, 20), + ); } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/BigNumberConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/BigNumberConverter.php index fef63fd00..99b88b3bf 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/BigNumberConverter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/BigNumberConverter.php @@ -27,10 +27,7 @@ */ class BigNumberConverter implements NumberConverterInterface { - /** - * @var NumberConverterInterface - */ - private $converter; + private NumberConverterInterface $converter; public function __construct() { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php index 501eac0fa..043c3c43d 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php @@ -26,14 +26,8 @@ */ class GenericNumberConverter implements NumberConverterInterface { - /** - * @var CalculatorInterface - */ - private $calculator; - - public function __construct(CalculatorInterface $calculator) + public function __construct(private CalculatorInterface $calculator) { - $this->calculator = $calculator; } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php index 7390dad83..b6bca9ee2 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php @@ -29,10 +29,7 @@ */ class BigNumberTimeConverter implements TimeConverterInterface { - /** - * @var TimeConverterInterface - */ - private $converter; + private TimeConverterInterface $converter; public function __construct() { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php index a8aa64b73..f6b60abbe 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php @@ -50,14 +50,8 @@ class GenericTimeConverter implements TimeConverterInterface */ private const MICROSECOND_INTERVALS = '10'; - /** - * @var CalculatorInterface - */ - private $calculator; - - public function __construct(CalculatorInterface $calculator) + public function __construct(private CalculatorInterface $calculator) { - $this->calculator = $calculator; } public function calculateTime(string $seconds, string $microseconds): Hexadecimal diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php index 538d2f2f6..66009f14d 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php @@ -58,20 +58,9 @@ class PhpTimeConverter implements TimeConverterInterface */ private const MICROSECOND_INTERVALS = 10; - /** - * @var CalculatorInterface - */ - private $calculator; - - /** - * @var TimeConverterInterface - */ - private $fallbackConverter; - - /** - * @var int - */ - private $phpPrecision; + private int $phpPrecision; + private CalculatorInterface $calculator; + private TimeConverterInterface $fallbackConverter; public function __construct( ?CalculatorInterface $calculator = null, @@ -132,11 +121,11 @@ public function convertTime(Hexadecimal $uuidTimestamp): Time } /** - * @param int|float $time The time to split into seconds and microseconds + * @param float|int $time The time to split into seconds and microseconds * * @return string[] */ - private function splitTime($time): array + private function splitTime(float | int $time): array { $split = explode('.', (string) $time, 2); diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php new file mode 100644 index 000000000..4d6d0a8a7 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php @@ -0,0 +1,90 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Converter\Time; + +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Math\RoundingMode; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; + +use function explode; +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values + * consisting of milliseconds elapsed since the Unix Epoch + * + * @psalm-immutable + */ +class UnixTimeConverter implements TimeConverterInterface +{ + private const MILLISECONDS = 1000; + + public function __construct(private CalculatorInterface $calculator) + { + } + + public function calculateTime(string $seconds, string $microseconds): Hexadecimal + { + $timestamp = new Time($seconds, $microseconds); + + // Convert the seconds into milliseconds. + $sec = $this->calculator->multiply( + $timestamp->getSeconds(), + new IntegerObject(self::MILLISECONDS), + ); + + // Convert the microseconds into milliseconds; the scale is zero because + // we need to discard the fractional part. + $usec = $this->calculator->divide( + RoundingMode::DOWN, // Always round down to stay in the previous millisecond. + 0, + $timestamp->getMicroseconds(), + new IntegerObject(self::MILLISECONDS), + ); + + /** @var IntegerObject $unixTime */ + $unixTime = $this->calculator->add($sec, $usec); + + $unixTimeHex = str_pad( + $this->calculator->toHexadecimal($unixTime)->toString(), + 12, + '0', + STR_PAD_LEFT + ); + + return new Hexadecimal($unixTimeHex); + } + + public function convertTime(Hexadecimal $uuidTimestamp): Time + { + $milliseconds = $this->calculator->toInteger($uuidTimestamp); + + $unixTimestamp = $this->calculator->divide( + RoundingMode::HALF_UP, + 6, + $milliseconds, + new IntegerObject(self::MILLISECONDS) + ); + + $split = explode('.', (string) $unixTimestamp, 2); + + return new Time($split[0], $split[1] ?? '0'); + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidInterface.php index ed6d9dec8..ac01a79cf 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidInterface.php @@ -18,8 +18,7 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; /** - * This interface encapsulates deprecated methods for ramsey/uuid; this - * interface and its methods will be removed in ramsey/uuid 5.0.0. + * This interface encapsulates deprecated methods for ramsey/uuid * * @psalm-immutable */ @@ -123,12 +122,6 @@ public function getTimeMidHex(): string; */ public function getTimestampHex(): string; - /** - * @deprecated In ramsey/uuid version 5.0.0, this will be removed from this - * interface. It has moved to {@see \Ramsey\Uuid\Rfc4122\UuidInterface::getUrn()}. - */ - public function getUrn(): string; - /** * @deprecated Use {@see UuidInterface::getFields()} to get a * {@see FieldsInterface} instance. If it is a diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php index 342829523..d3fbb0ccb 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php @@ -17,10 +17,8 @@ use DateTimeImmutable; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\UnsupportedOperationException; -use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Throwable; use function str_pad; @@ -32,29 +30,17 @@ * This trait encapsulates deprecated methods for ramsey/uuid; this trait and * its methods will be removed in ramsey/uuid 5.0.0. * + * @deprecated This trait and its methods will be removed in ramsey/uuid 5.0.0. + * * @psalm-immutable */ trait DeprecatedUuidMethodsTrait { - /** - * @var Rfc4122FieldsInterface - */ - protected $fields; - - /** - * @var NumberConverterInterface - */ - protected $numberConverter; - - /** - * @var TimeConverterInterface - */ - protected $timeConverter; - /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -65,8 +51,9 @@ public function getClockSeqHiAndReserved(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()}. */ public function getClockSeqHiAndReservedHex(): string { @@ -75,8 +62,9 @@ public function getClockSeqHiAndReservedHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -87,8 +75,9 @@ public function getClockSeqLow(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()}. */ public function getClockSeqLowHex(): string { @@ -97,8 +86,9 @@ public function getClockSeqLowHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -109,8 +99,9 @@ public function getClockSequence(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()}. */ public function getClockSequenceHex(): string { @@ -157,7 +148,7 @@ public function getDateTime(): DateTimeInterface /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * * @return string[] */ @@ -219,10 +210,11 @@ public function getMostSignificantBitsHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getNode()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getNode(): string { @@ -231,8 +223,9 @@ public function getNode(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getNode()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()}. */ public function getNodeHex(): string { @@ -241,8 +234,9 @@ public function getNodeHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -253,8 +247,9 @@ public function getTimeHiAndVersion(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()}. */ public function getTimeHiAndVersionHex(): string { @@ -263,10 +258,11 @@ public function getTimeHiAndVersionHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getTimeLow(): string { @@ -275,8 +271,9 @@ public function getTimeLow(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()}. */ public function getTimeLowHex(): string { @@ -285,10 +282,11 @@ public function getTimeLowHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getTimeMid(): string { @@ -297,8 +295,9 @@ public function getTimeMid(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()}. */ public function getTimeMidHex(): string { @@ -307,10 +306,11 @@ public function getTimeMidHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()} and use + * the arbitrary-precision math library of your choice to convert it to + * a string integer. */ public function getTimestamp(): string { @@ -323,8 +323,9 @@ public function getTimestamp(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()}. */ public function getTimestampHex(): string { @@ -335,20 +336,9 @@ public function getTimestampHex(): string return $this->fields->getTimestamp()->toString(); } - /** - * @deprecated This has moved to {@see Rfc4122FieldsInterface::getUrn()} and - * is available on {@see \Ramsey\Uuid\Rfc4122\UuidV1}, - * {@see \Ramsey\Uuid\Rfc4122\UuidV3}, {@see \Ramsey\Uuid\Rfc4122\UuidV4}, - * and {@see \Ramsey\Uuid\Rfc4122\UuidV5}. - */ - public function getUrn(): string - { - return 'urn:uuid:' . $this->toString(); - } - /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. */ @@ -359,7 +349,7 @@ public function getVariant(): ?int /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. */ diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/FeatureSet.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/FeatureSet.php index a8ab2fdbb..b9af869f9 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/FeatureSet.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/FeatureSet.php @@ -14,7 +14,6 @@ namespace Ramsey\Uuid; -use Ramsey\Uuid\Builder\BuilderCollection; use Ramsey\Uuid\Builder\FallbackBuilder; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; @@ -36,6 +35,7 @@ use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorFactory; use Ramsey\Uuid\Generator\TimeGeneratorInterface; +use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Guid\GuidBuilder; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Math\CalculatorInterface; @@ -43,7 +43,6 @@ use Ramsey\Uuid\Provider\Dce\SystemDceSecurityProvider; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; -use Ramsey\Uuid\Provider\Node\NodeProviderCollection; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Provider\Node\SystemNodeProvider; use Ramsey\Uuid\Provider\NodeProviderInterface; @@ -63,92 +62,25 @@ */ class FeatureSet { - /** - * @var bool - */ - private $disableBigNumber = false; - - /** - * @var bool - */ - private $disable64Bit = false; - - /** - * @var bool - */ - private $ignoreSystemNode = false; - - /** - * @var bool - */ - private $enablePecl = false; - - /** - * @var UuidBuilderInterface - */ - private $builder; - - /** - * @var CodecInterface - */ - private $codec; - - /** - * @var DceSecurityGeneratorInterface - */ - private $dceSecurityGenerator; - - /** - * @var NameGeneratorInterface - */ - private $nameGenerator; - - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var TimeGeneratorInterface - */ - private $timeGenerator; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @var CalculatorInterface - */ - private $calculator; + private ?TimeProviderInterface $timeProvider = null; + private CalculatorInterface $calculator; + private CodecInterface $codec; + private DceSecurityGeneratorInterface $dceSecurityGenerator; + private NameGeneratorInterface $nameGenerator; + private NodeProviderInterface $nodeProvider; + private NumberConverterInterface $numberConverter; + private RandomGeneratorInterface $randomGenerator; + private TimeConverterInterface $timeConverter; + private TimeGeneratorInterface $timeGenerator; + private TimeGeneratorInterface $unixTimeGenerator; + private UuidBuilderInterface $builder; + private ValidatorInterface $validator; /** * @param bool $useGuids True build UUIDs using the GuidStringCodec * @param bool $force32Bit True to force the use of 32-bit functionality * (primarily for testing purposes) - * @param bool $forceNoBigNumber True to disable the use of moontoast/math - * (primarily for testing purposes) + * @param bool $forceNoBigNumber (obsolete) * @param bool $ignoreSystemNode True to disable attempts to check for the * system node ID (primarily for testing purposes) * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator @@ -156,25 +88,23 @@ class FeatureSet */ public function __construct( bool $useGuids = false, - bool $force32Bit = false, + private bool $force32Bit = false, bool $forceNoBigNumber = false, - bool $ignoreSystemNode = false, - bool $enablePecl = false + private bool $ignoreSystemNode = false, + private bool $enablePecl = false ) { - $this->disableBigNumber = $forceNoBigNumber; - $this->disable64Bit = $force32Bit; - $this->ignoreSystemNode = $ignoreSystemNode; - $this->enablePecl = $enablePecl; - + $this->randomGenerator = $this->buildRandomGenerator(); $this->setCalculator(new BrickMathCalculator()); $this->builder = $this->buildUuidBuilder($useGuids); $this->codec = $this->buildCodec($useGuids); $this->nodeProvider = $this->buildNodeProvider(); $this->nameGenerator = $this->buildNameGenerator(); - $this->randomGenerator = $this->buildRandomGenerator(); $this->setTimeProvider(new SystemTimeProvider()); $this->setDceSecurityProvider(new SystemDceSecurityProvider()); $this->validator = new GenericValidator(); + + assert($this->timeProvider !== null); + $this->unixTimeGenerator = $this->buildUnixTimeGenerator(); } /** @@ -257,6 +187,14 @@ public function getTimeGenerator(): TimeGeneratorInterface return $this->timeGenerator; } + /** + * Returns the Unix Epoch time generator configured for this environment + */ + public function getUnixTimeGenerator(): TimeGeneratorInterface + { + return $this->unixTimeGenerator; + } + /** * Returns the validator configured for this environment */ @@ -294,7 +232,10 @@ public function setDceSecurityProvider(DceSecurityProviderInterface $dceSecurity public function setNodeProvider(NodeProviderInterface $nodeProvider): void { $this->nodeProvider = $nodeProvider; - $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + + if (isset($this->timeProvider)) { + $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + } } /** @@ -350,10 +291,10 @@ private function buildNodeProvider(): NodeProviderInterface return new RandomNodeProvider(); } - return new FallbackNodeProvider(new NodeProviderCollection([ + return new FallbackNodeProvider([ new SystemNodeProvider(), new RandomNodeProvider(), - ])); + ]); } /** @@ -395,6 +336,14 @@ private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGe ))->getGenerator(); } + /** + * Returns a Unix Epoch time generator configured for this environment + */ + private function buildUnixTimeGenerator(): TimeGeneratorInterface + { + return new UnixTimeGenerator($this->randomGenerator); + } + /** * Returns a name generator configured for this environment */ @@ -432,11 +381,10 @@ private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface return new GuidBuilder($this->numberConverter, $this->timeConverter); } - /** @psalm-suppress ImpureArgument */ - return new FallbackBuilder(new BuilderCollection([ + return new FallbackBuilder([ new Rfc4122UuidBuilder($this->numberConverter, $this->timeConverter), new NonstandardUuidBuilder($this->numberConverter, $this->timeConverter), - ])); + ]); } /** @@ -444,6 +392,6 @@ private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface */ private function is64BitSystem(): bool { - return PHP_INT_SIZE === 8 && !$this->disable64Bit; + return PHP_INT_SIZE === 8 && !$this->force32Bit; } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Fields/SerializableFieldsTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Fields/SerializableFieldsTrait.php index 16e6525da..3d36b6f12 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Fields/SerializableFieldsTrait.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Fields/SerializableFieldsTrait.php @@ -56,22 +56,23 @@ public function __serialize(): array /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - if (strlen($serialized) === 16) { - $this->__construct($serialized); + if (strlen($data) === 16) { + $this->__construct($data); } else { - $this->__construct(base64_decode($serialized)); + $this->__construct(base64_decode($data)); } } /** - * @param array{bytes: string} $data + * @param array{bytes?: string} $data + * + * @psalm-suppress UnusedMethodCall */ public function __unserialize(array $data): void { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/CombGenerator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/CombGenerator.php index 49b09381d..0e8870608 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/CombGenerator.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/CombGenerator.php @@ -61,22 +61,10 @@ class CombGenerator implements RandomGeneratorInterface { public const TIMESTAMP_BYTES = 6; - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var NumberConverterInterface - */ - private $converter; - public function __construct( - RandomGeneratorInterface $generator, - NumberConverterInterface $numberConverter + private RandomGeneratorInterface $generator, + private NumberConverterInterface $numberConverter ) { - $this->converter = $numberConverter; - $this->randomGenerator = $generator; } /** @@ -87,7 +75,7 @@ public function __construct( */ public function generate(int $length): string { - if ($length < self::TIMESTAMP_BYTES || $length < 0) { + if ($length < self::TIMESTAMP_BYTES) { throw new InvalidArgumentException( 'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES ); @@ -95,11 +83,11 @@ public function generate(int $length): string $hash = ''; if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) { - $hash = $this->randomGenerator->generate($length - self::TIMESTAMP_BYTES); + $hash = $this->generator->generate($length - self::TIMESTAMP_BYTES); } $lsbTime = str_pad( - $this->converter->toHex($this->timestamp()), + $this->numberConverter->toHex($this->timestamp()), self::TIMESTAMP_BYTES * 2, '0', STR_PAD_LEFT diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DceSecurityGenerator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DceSecurityGenerator.php index aca8c5db7..37ba78131 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DceSecurityGenerator.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DceSecurityGenerator.php @@ -52,29 +52,11 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface */ private const CLOCK_SEQ_LOW = 0; - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeGeneratorInterface - */ - private $timeGenerator; - - /** - * @var DceSecurityProviderInterface - */ - private $dceSecurityProvider; - public function __construct( - NumberConverterInterface $numberConverter, - TimeGeneratorInterface $timeGenerator, - DceSecurityProviderInterface $dceSecurityProvider + private NumberConverterInterface $numberConverter, + private TimeGeneratorInterface $timeGenerator, + private DceSecurityProviderInterface $dceSecurityProvider ) { - $this->numberConverter = $numberConverter; - $this->timeGenerator = $timeGenerator; - $this->dceSecurityProvider = $dceSecurityProvider; } public function generate( @@ -153,8 +135,7 @@ public function generate( // Replace bytes in the time-based UUID with DCE Security values. $bytes = substr_replace($bytes, $identifierBytes, 0, 4); - $bytes = substr_replace($bytes, $domainByte, 9, 1); - return $bytes; + return substr_replace($bytes, $domainByte, 9, 1); } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DefaultTimeGenerator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DefaultTimeGenerator.php index d245c7bcc..ea1e2a6ff 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DefaultTimeGenerator.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/DefaultTimeGenerator.php @@ -23,11 +23,11 @@ use Ramsey\Uuid\Type\Hexadecimal; use Throwable; -use function ctype_xdigit; use function dechex; use function hex2bin; use function is_int; use function pack; +use function preg_match; use function sprintf; use function str_pad; use function strlen; @@ -40,29 +40,11 @@ */ class DefaultTimeGenerator implements TimeGeneratorInterface { - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - public function __construct( - NodeProviderInterface $nodeProvider, - TimeConverterInterface $timeConverter, - TimeProviderInterface $timeProvider + private NodeProviderInterface $nodeProvider, + private TimeConverterInterface $timeConverter, + private TimeProviderInterface $timeProvider ) { - $this->nodeProvider = $nodeProvider; - $this->timeConverter = $timeConverter; - $this->timeProvider = $timeProvider; } /** @@ -121,13 +103,13 @@ public function generate($node = null, ?int $clockSeq = null): string * Uses the node provider given when constructing this instance to get * the node ID (usually a MAC address) * - * @param string|int|null $node A node value that may be used to override the node provider + * @param int|string|null $node A node value that may be used to override the node provider * * @return string 6-byte binary string representation of the node * * @throws InvalidArgumentException */ - private function getValidNode($node): string + private function getValidNode(int | string | null $node): string { if ($node === null) { $node = $this->nodeProvider->getNode(); @@ -138,7 +120,7 @@ private function getValidNode($node): string $node = dechex($node); } - if (!ctype_xdigit((string) $node) || strlen((string) $node) > 12) { + if (!preg_match('/^[A-Fa-f0-9]+$/', (string) $node) || strlen((string) $node) > 12) { throw new InvalidArgumentException('Invalid node value'); } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php index 3780c5c60..6a6d1aec3 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php @@ -33,21 +33,16 @@ class PeclUuidNameGenerator implements NameGeneratorInterface /** @psalm-pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { - switch ($hashAlgorithm) { - case 'md5': - $uuid = uuid_generate_md5($ns->toString(), $name); - - break; - case 'sha1': - $uuid = uuid_generate_sha1($ns->toString(), $name); - - break; - default: - throw new NameException(sprintf( + $uuid = match ($hashAlgorithm) { + 'md5' => uuid_generate_md5($ns->toString(), $name), + 'sha1' => uuid_generate_sha1($ns->toString(), $name), + default => throw new NameException( + sprintf( 'Unable to hash namespace and name with algorithm \'%s\'', $hashAlgorithm - )); - } + ) + ), + }; return uuid_parse($uuid); } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomGeneratorInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomGeneratorInterface.php index 5c83cb4d8..1180b9764 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomGeneratorInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomGeneratorInterface.php @@ -22,7 +22,7 @@ interface RandomGeneratorInterface /** * Generates a string of randomized binary data * - * @param int $length The number of bytes of random binary data to generate + * @param int<1, max> $length The number of bytes of random binary data to generate * * @return string A binary string */ diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomLibAdapter.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomLibAdapter.php index 24ed56920..fd0ccc8aa 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomLibAdapter.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/RandomLibAdapter.php @@ -21,14 +21,15 @@ * RandomLibAdapter generates strings of random binary data using the * paragonie/random-lib library * + * @deprecated This class will be removed in 5.0.0. Use the default + * RandomBytesGenerator or implement your own generator that implements + * RandomGeneratorInterface. + * * @link https://packagist.org/packages/paragonie/random-lib paragonie/random-lib */ class RandomLibAdapter implements RandomGeneratorInterface { - /** - * @var Generator - */ - private $generator; + private Generator $generator; /** * Constructs a RandomLibAdapter diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/TimeGeneratorFactory.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/TimeGeneratorFactory.php index 3d55fc4d6..8d06fc3ae 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/TimeGeneratorFactory.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/TimeGeneratorFactory.php @@ -24,29 +24,11 @@ */ class TimeGeneratorFactory { - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - public function __construct( - NodeProviderInterface $nodeProvider, - TimeConverterInterface $timeConverter, - TimeProviderInterface $timeProvider + private NodeProviderInterface $nodeProvider, + private TimeConverterInterface $timeConverter, + private TimeProviderInterface $timeProvider ) { - $this->nodeProvider = $nodeProvider; - $this->timeConverter = $timeConverter; - $this->timeProvider = $timeProvider; } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/UnixTimeGenerator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/UnixTimeGenerator.php new file mode 100644 index 000000000..af94decf2 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Generator/UnixTimeGenerator.php @@ -0,0 +1,169 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Brick\Math\BigInteger; +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +use function hash; +use function pack; +use function str_pad; +use function strlen; +use function substr; +use function substr_replace; +use function unpack; + +use const PHP_INT_SIZE; +use const STR_PAD_LEFT; + +/** + * UnixTimeGenerator generates bytes that combine a 48-bit timestamp in + * milliseconds since the Unix Epoch with 80 random bits + * + * Code and concepts within this class are borrowed from the symfony/uid package + * and are used under the terms of the MIT license distributed with symfony/uid. + * + * symfony/uid is copyright (c) Fabien Potencier. + * + * @link https://symfony.com/components/Uid Symfony Uid component + * @link https://github.com/symfony/uid/blob/4f9f537e57261519808a7ce1d941490736522bbc/UuidV7.php Symfony UuidV7 class + * @link https://github.com/symfony/uid/blob/6.2/LICENSE MIT License + */ +class UnixTimeGenerator implements TimeGeneratorInterface +{ + private static string $time = ''; + private static ?string $seed = null; + private static int $seedIndex = 0; + + /** @var int[] */ + private static array $rand = []; + + /** @var int[] */ + private static array $seedParts; + + public function __construct( + private RandomGeneratorInterface $randomGenerator, + private int $intSize = PHP_INT_SIZE + ) { + } + + /** + * @param Hexadecimal|int|string|null $node Unused in this generator + * @param int|null $clockSeq Unused in this generator + * @param DateTimeInterface $dateTime A date-time instance to use when + * generating bytes + * + * @inheritDoc + */ + public function generate($node = null, ?int $clockSeq = null, ?DateTimeInterface $dateTime = null): string + { + $time = ($dateTime ?? new DateTimeImmutable('now'))->format('Uv'); + + if ($time > self::$time || ($dateTime !== null && $time !== self::$time)) { + $this->randomize($time); + } else { + $time = $this->increment(); + } + + if ($this->intSize >= 8) { + $time = substr(pack('J', (int) $time), -6); + } else { + $time = str_pad(BigInteger::of($time)->toBytes(false), 6, "\x00", STR_PAD_LEFT); + } + + /** @var non-empty-string */ + return $time . pack('n*', self::$rand[1], self::$rand[2], self::$rand[3], self::$rand[4], self::$rand[5]); + } + + private function randomize(string $time): void + { + if (self::$seed === null) { + $seed = $this->randomGenerator->generate(16); + self::$seed = $seed; + } else { + $seed = $this->randomGenerator->generate(10); + } + + /** @var int[] $rand */ + $rand = unpack('n*', $seed); + $rand[1] &= 0x03ff; + + self::$rand = $rand; + self::$time = $time; + } + + /** + * Special thanks to Nicolas Grekas for sharing the following information: + * + * Within the same ms, we increment the rand part by a random 24-bit number. + * + * Instead of getting this number from random_bytes(), which is slow, we get + * it by sha512-hashing self::$seed. This produces 64 bytes of entropy, + * which we need to split in a list of 24-bit numbers. unpack() first splits + * them into 16 x 32-bit numbers; we take the first byte of each of these + * numbers to get 5 extra 24-bit numbers. Then, we consume those numbers + * one-by-one and run this logic every 21 iterations. + * + * self::$rand holds the random part of the UUID, split into 5 x 16-bit + * numbers for x86 portability. We increment this random part by the next + * 24-bit number in the self::$seedParts list and decrement + * self::$seedIndex. + * + * @link https://twitter.com/nicolasgrekas/status/1583356938825261061 Tweet from Nicolas Grekas + */ + private function increment(): string + { + if (self::$seedIndex === 0 && self::$seed !== null) { + self::$seed = hash('sha512', self::$seed, true); + + /** @var int[] $s */ + $s = unpack('l*', self::$seed); + $s[] = ($s[1] >> 8 & 0xff0000) | ($s[2] >> 16 & 0xff00) | ($s[3] >> 24 & 0xff); + $s[] = ($s[4] >> 8 & 0xff0000) | ($s[5] >> 16 & 0xff00) | ($s[6] >> 24 & 0xff); + $s[] = ($s[7] >> 8 & 0xff0000) | ($s[8] >> 16 & 0xff00) | ($s[9] >> 24 & 0xff); + $s[] = ($s[10] >> 8 & 0xff0000) | ($s[11] >> 16 & 0xff00) | ($s[12] >> 24 & 0xff); + $s[] = ($s[13] >> 8 & 0xff0000) | ($s[14] >> 16 & 0xff00) | ($s[15] >> 24 & 0xff); + + self::$seedParts = $s; + self::$seedIndex = 21; + } + + self::$rand[5] = 0xffff & $carry = self::$rand[5] + (self::$seedParts[self::$seedIndex--] & 0xffffff); + self::$rand[4] = 0xffff & $carry = self::$rand[4] + ($carry >> 16); + self::$rand[3] = 0xffff & $carry = self::$rand[3] + ($carry >> 16); + self::$rand[2] = 0xffff & $carry = self::$rand[2] + ($carry >> 16); + self::$rand[1] += $carry >> 16; + + if (0xfc00 & self::$rand[1]) { + $time = self::$time; + $mtime = (int) substr($time, -9); + + if ($this->intSize >= 8 || strlen($time) < 10) { + $time = (string) ((int) $time + 1); + } elseif ($mtime === 999999999) { + $time = (1 + (int) substr($time, 0, -9)) . '000000000'; + } else { + $mtime++; + $time = substr_replace($time, str_pad((string) $mtime, 9, '0', STR_PAD_LEFT), -9); + } + + $this->randomize($time); + } + + return self::$time; + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/Fields.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/Fields.php index d8a1a2b10..0fc5d1c9b 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/Fields.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/Fields.php @@ -17,6 +17,7 @@ use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Rfc4122\FieldsInterface; +use Ramsey\Uuid\Rfc4122\MaxTrait; use Ramsey\Uuid\Rfc4122\NilTrait; use Ramsey\Uuid\Rfc4122\VariantTrait; use Ramsey\Uuid\Rfc4122\VersionTrait; @@ -44,16 +45,12 @@ */ final class Fields implements FieldsInterface { + use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * @@ -61,17 +58,15 @@ final class Fields implements FieldsInterface * @throws InvalidArgumentException if the byte string does not represent a GUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - $this->bytes = $bytes; - if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC ' @@ -149,7 +144,13 @@ public function getTimestamp(): Hexadecimal public function getClockSeq(): Hexadecimal { - $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + if ($this->isMax()) { + $clockSeq = 0xffff; + } elseif ($this->isNil()) { + $clockSeq = 0x0000; + } else { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } @@ -171,7 +172,7 @@ public function getNode(): Hexadecimal public function getVersion(): ?int { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return null; } @@ -183,7 +184,7 @@ public function getVersion(): ?int private function isCorrectVariant(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/GuidBuilder.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/GuidBuilder.php index 758dd6b7f..c036bb20b 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/GuidBuilder.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Guid/GuidBuilder.php @@ -31,16 +31,6 @@ */ class GuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - /** * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Guid @@ -48,11 +38,9 @@ class GuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Lazy/LazyUuidFromString.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Lazy/LazyUuidFromString.php index 8ba757964..c0b47bbf2 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Lazy/LazyUuidFromString.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Lazy/LazyUuidFromString.php @@ -18,8 +18,8 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; -use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\Rfc4122\UuidV6; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\UuidFactory; @@ -55,18 +55,14 @@ final class LazyUuidFromString implements UuidInterface { public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; + + private ?UuidInterface $unwrapped = null; + /** - * @var string - * @psalm-var non-empty-string + * @psalm-param non-empty-string $uuid */ - private $uuid; - /** @var UuidInterface|null */ - private $unwrapped; - - /** @psalm-param non-empty-string $uuid */ - public function __construct(string $uuid) + public function __construct(private string $uuid) { - $this->uuid = $uuid; } /** @psalm-pure */ @@ -105,19 +101,20 @@ public function __serialize(): array /** * {@inheritDoc} * - * @param string $serialized + * @param string $data * - * @psalm-param non-empty-string $serialized + * @psalm-param non-empty-string $data */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->uuid = $serialized; + $this->uuid = $data; } /** - * @param array{string: string} $data + * @param array{string?: string} $data * - * @psalm-param array{string: non-empty-string} $data + * @psalm-param array{string?: non-empty-string} $data + * @psalm-suppress UnusedMethodCall */ public function __unserialize(array $data): void { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/Fields.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/Fields.php index 927bc6a26..5dfe61076 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/Fields.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/Fields.php @@ -47,26 +47,19 @@ final class Fields implements FieldsInterface use SerializableFieldsTrait; use VariantTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - - $this->bytes = $bytes; } public function getBytes(): string @@ -130,4 +123,9 @@ public function isNil(): bool { return false; } + + public function isMax(): bool + { + return false; + } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidBuilder.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidBuilder.php index 0c8927738..82efd402f 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidBuilder.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidBuilder.php @@ -29,16 +29,6 @@ */ class UuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - /** * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Nonstandard\Uuid @@ -46,11 +36,9 @@ class UuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; } /** diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidV6.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidV6.php index 05586b3eb..7497dd101 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidV6.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Nonstandard/UuidV6.php @@ -14,39 +14,34 @@ namespace Ramsey\Uuid\Nonstandard; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Rfc4122\TimeTrait; use Ramsey\Uuid\Rfc4122\UuidInterface; use Ramsey\Uuid\Rfc4122\UuidV1; -use Ramsey\Uuid\Uuid; -use Throwable; - -use function hex2bin; -use function str_pad; -use function substr; - -use const STR_PAD_LEFT; +use Ramsey\Uuid\Uuid as BaseUuid; /** - * Ordered-time, or version 6, UUIDs include timestamp, clock sequence, and node - * values that are combined into a 128-bit unsigned integer + * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and + * node values that are combined into a 128-bit unsigned integer + * + * @deprecated Use {@see \Ramsey\Uuid\Rfc4122\UuidV6} instead. * * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs * * @psalm-immutable */ -final class UuidV6 extends Uuid implements UuidInterface +class UuidV6 extends BaseUuid implements UuidInterface { + use TimeTrait; + /** - * Creates a version 6 (time-based) UUID + * Creates a version 6 (reordered time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use @@ -62,39 +57,16 @@ public function __construct( CodecInterface $codec, TimeConverterInterface $timeConverter ) { - if ($fields->getVersion() !== Uuid::UUID_TYPE_PEABODY) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_REORDERED_TIME) { throw new InvalidArgumentException( 'Fields used to create a UuidV6 must represent a ' - . 'version 6 (ordered-time) UUID' + . 'version 6 (reordered time) UUID' ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 6 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } - /** * Converts this UUID into an instance of a version 1 UUID */ @@ -116,7 +88,7 @@ public function toUuidV1(): UuidV1 /** * Converts a version 1 UUID into an instance of a version 6 UUID */ - public static function fromUuidV1(UuidV1 $uuidV1): UuidV6 + public static function fromUuidV1(UuidV1 $uuidV1): \Ramsey\Uuid\Rfc4122\UuidV6 { $hex = $uuidV1->getHex()->toString(); $hex = substr($hex, 13, 3) diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php index 6d6240b7a..d5b6cf0c0 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php @@ -21,7 +21,6 @@ use function escapeshellarg; use function preg_split; use function str_getcsv; -use function strpos; use function strrpos; use function strtolower; use function strtoupper; @@ -42,6 +41,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface */ public function getUid(): IntegerObject { + /** @var int|float|string|IntegerObject|null $uid */ static $uid = null; if ($uid instanceof IntegerObject) { @@ -72,6 +72,7 @@ public function getUid(): IntegerObject */ public function getGid(): IntegerObject { + /** @var int|float|string|IntegerObject|null $gid */ static $gid = null; if ($gid instanceof IntegerObject) { @@ -104,15 +105,10 @@ private function getSystemUid(): string return ''; } - switch ($this->getOs()) { - case 'WIN': - return $this->getWindowsUid(); - case 'DAR': - case 'FRE': - case 'LIN': - default: - return trim((string) shell_exec('id -u')); - } + return match ($this->getOs()) { + 'WIN' => $this->getWindowsUid(), + default => trim((string) shell_exec('id -u')), + }; } /** @@ -124,15 +120,10 @@ private function getSystemGid(): string return ''; } - switch ($this->getOs()) { - case 'WIN': - return $this->getWindowsGid(); - case 'DAR': - case 'FRE': - case 'LIN': - default: - return trim((string) shell_exec('id -g')); - } + return match ($this->getOs()) { + 'WIN' => $this->getWindowsGid(), + default => trim((string) shell_exec('id -g')), + }; } /** @@ -142,7 +133,7 @@ private function hasShellExec(): bool { $disabledFunctions = strtolower((string) ini_get('disable_functions')); - return strpos($disabledFunctions, 'shell_exec') === false; + return !str_contains($disabledFunctions, 'shell_exec'); } /** @@ -150,7 +141,13 @@ private function hasShellExec(): bool */ private function getOs(): string { - return strtoupper(substr(constant('PHP_OS'), 0, 3)); + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + + return strtoupper(substr($phpOs, 0, 3)); } /** @@ -229,6 +226,6 @@ private function getWindowsGid(): string return ''; } - return trim((string) substr($sid, $lastHyphen + 1)); + return trim(substr($sid, $lastHyphen + 1)); } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php index cad01045c..d2eb20b70 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php @@ -25,23 +25,17 @@ class FallbackNodeProvider implements NodeProviderInterface { /** - * @var NodeProviderCollection + * @param iterable $providers Array of node providers */ - private $nodeProviders; - - /** - * @param NodeProviderCollection $providers Array of node providers - */ - public function __construct(NodeProviderCollection $providers) + public function __construct(private iterable $providers) { - $this->nodeProviders = $providers; } public function getNode(): Hexadecimal { $lastProviderException = null; - foreach ($this->nodeProviders as $provider) { + foreach ($this->providers as $provider) { try { return $provider->getNode(); } catch (NodeException $exception) { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php index 536cb6034..1b979faee 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php @@ -21,6 +21,11 @@ /** * A collection of NodeProviderInterface objects * + * @deprecated this class has been deprecated, and will be removed in 5.0.0. The use-case for this class comes from + * a pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced + * at runtime: that is no longer necessary, now that you can safely verify your code to be correct, and use + * more generic types like `iterable` instead. + * * @extends AbstractCollection */ class NodeProviderCollection extends AbstractCollection diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php index 51f1b02ea..0f7536a82 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php @@ -32,10 +32,7 @@ */ class StaticNodeProvider implements NodeProviderInterface { - /** - * @var Hexadecimal - */ - private $node; + private Hexadecimal $node; /** * @param Hexadecimal $node The static node value to use diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php index d512f22aa..a03c93b4d 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php @@ -27,8 +27,8 @@ use function preg_match; use function preg_match_all; use function reset; +use function str_contains; use function str_replace; -use function strpos; use function strtolower; use function strtoupper; use function substr; @@ -100,12 +100,18 @@ protected function getIfconfig(): string { $disabledFunctions = strtolower((string) ini_get('disable_functions')); - if (strpos($disabledFunctions, 'passthru') !== false) { + if (str_contains($disabledFunctions, 'passthru')) { return ''; } + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + ob_start(); - switch (strtoupper(substr(constant('PHP_OS'), 0, 3))) { + switch (strtoupper(substr($phpOs, 0, 3))) { case 'WIN': passthru('ipconfig /all 2>&1'); @@ -127,12 +133,15 @@ protected function getIfconfig(): string $ifconfig = (string) ob_get_clean(); - $node = ''; if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) { - $node = $matches[1][0] ?? ''; + foreach ($matches[1] as $iface) { + if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') { + return $iface; + } + } } - return $node; + return ''; } /** @@ -142,13 +151,20 @@ protected function getSysfs(): string { $mac = ''; - if (strtoupper(constant('PHP_OS')) === 'LINUX') { + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + + if (strtoupper($phpOs) === 'LINUX') { $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); if ($addressPaths === false || count($addressPaths) === 0) { return ''; } + /** @var array $macs */ $macs = []; array_walk($addressPaths, function (string $addressPath) use (&$macs): void { @@ -157,7 +173,10 @@ protected function getSysfs(): string } }); - $macs = array_map('trim', $macs); + /** @var callable $trim */ + $trim = 'trim'; + + $macs = array_map($trim, $macs); // Remove invalid entries. $macs = array_filter($macs, function (string $address) { @@ -165,6 +184,7 @@ protected function getSysfs(): string && preg_match(self::SYSFS_PATTERN, $address); }); + /** @var string|bool $mac */ $mac = reset($macs); } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php index b8bfd7215..526c8ff46 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php @@ -19,21 +19,15 @@ use Ramsey\Uuid\Type\Time; /** - * FixedTimeProvider uses an known time to provide the time + * FixedTimeProvider uses a known time to provide the time * * This provider allows the use of a previously-generated, or known, time * when generating time-based UUIDs. */ class FixedTimeProvider implements TimeProviderInterface { - /** - * @var Time - */ - private $fixedTime; - - public function __construct(Time $time) + public function __construct(private Time $time) { - $this->fixedTime = $time; } /** @@ -43,7 +37,7 @@ public function __construct(Time $time) */ public function setUsec($value): void { - $this->fixedTime = new Time($this->fixedTime->getSeconds(), $value); + $this->time = new Time($this->time->getSeconds(), $value); } /** @@ -53,11 +47,11 @@ public function setUsec($value): void */ public function setSec($value): void { - $this->fixedTime = new Time($value, $this->fixedTime->getMicroseconds()); + $this->time = new Time($value, $this->time->getMicroseconds()); } public function getTime(): Time { - return $this->fixedTime; + return $this->time; } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Fields.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Fields.php index 2ccc20bb6..9acf810c2 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Fields.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Fields.php @@ -40,16 +40,12 @@ */ final class Fields implements FieldsInterface { + use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * @@ -57,17 +53,15 @@ final class Fields implements FieldsInterface * @throws InvalidArgumentException if the byte string does not represent an RFC 4122 UUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - $this->bytes = $bytes; - if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC 4122 variant' @@ -88,7 +82,13 @@ public function getBytes(): string public function getClockSeq(): Hexadecimal { - $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + if ($this->isMax()) { + $clockSeq = 0xffff; + } elseif ($this->isNil()) { + $clockSeq = 0x0000; + } else { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } @@ -140,52 +140,53 @@ public function getTimeMid(): Hexadecimal */ public function getTimestamp(): Hexadecimal { - switch ($this->getVersion()) { - case Uuid::UUID_TYPE_DCE_SECURITY: - $timestamp = sprintf( - '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, - $this->getTimeMid()->toString(), - '' - ); - - break; - case Uuid::UUID_TYPE_PEABODY: - $timestamp = sprintf( - '%08s%04s%03x', - $this->getTimeLow()->toString(), - $this->getTimeMid()->toString(), - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff - ); - - break; - default: - $timestamp = sprintf( - '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, - $this->getTimeMid()->toString(), - $this->getTimeLow()->toString() - ); - } + $timestamp = match ($this->getVersion()) { + Uuid::UUID_TYPE_DCE_SECURITY => sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + '' + ), + Uuid::UUID_TYPE_REORDERED_TIME => sprintf( + '%08s%04s%03x', + $this->getTimeLow()->toString(), + $this->getTimeMid()->toString(), + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff + ), + // The Unix timestamp in version 7 UUIDs is a 48-bit number, + // but for consistency, we will return a 60-bit number, padded + // to the left with zeros. + Uuid::UUID_TYPE_UNIX_TIME => sprintf( + '%011s%04s', + $this->getTimeLow()->toString(), + $this->getTimeMid()->toString(), + ), + default => sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + ), + }; return new Hexadecimal($timestamp); } public function getVersion(): ?int { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return null; } - /** @var array $parts */ + /** @var int[] $parts */ $parts = unpack('n*', $this->bytes); - return (int) $parts[4] >> 12; + return $parts[4] >> 12; } private function isCorrectVariant(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/FieldsInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/FieldsInterface.php index a303525d6..2241cf574 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/FieldsInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/FieldsInterface.php @@ -103,11 +103,13 @@ public function getVariant(): int; * The version number describes how the UUID was generated and has the * following meaning: * - * 1. Time-based UUID + * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 + * 6. Reordered time UUID + * 7. Unix Epoch time UUID * * This returns `null` if the UUID is not an RFC 4122 variant, since version * is only meaningful for this variant. diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxTrait.php new file mode 100644 index 000000000..dedb72798 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxTrait.php @@ -0,0 +1,41 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +/** + * Provides common functionality for max UUIDs + * + * The max UUID is special form of UUID that is specified to have all 128 bits + * set to one. It is the inverse of the nil UUID. + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID + * + * @psalm-immutable + */ +trait MaxTrait +{ + /** + * Returns the bytes that comprise the fields + */ + abstract public function getBytes(): string; + + /** + * Returns true if the byte string represents a max UUID + */ + public function isMax(): bool + { + return $this->getBytes() === "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxUuid.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxUuid.php new file mode 100644 index 000000000..e5ffa72c6 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/MaxUuid.php @@ -0,0 +1,27 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Uuid; + +/** + * The max UUID is special form of UUID that is specified to have all 128 bits + * set to one + * + * @psalm-immutable + */ +final class MaxUuid extends Uuid implements UuidInterface +{ +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/TimeTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/TimeTrait.php new file mode 100644 index 000000000..5d939fac6 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/TimeTrait.php @@ -0,0 +1,55 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Throwable; + +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * Provides common functionality for getting the time from a time-based UUID + * + * @psalm-immutable + */ +trait TimeTrait +{ + /** + * Returns a DateTimeInterface object representing the timestamp associated + * with the UUID + * + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing + * the timestamp of a time-based UUID + */ + public function getDateTime(): DateTimeInterface + { + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidBuilder.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidBuilder.php index 736931af2..2c2677db7 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidBuilder.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidBuilder.php @@ -17,11 +17,13 @@ use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\Time\UnixTimeConverter; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\Exception\UnsupportedOperationException; -use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Rfc4122\UuidInterface as Rfc4122UuidInterface; +use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use Throwable; @@ -32,15 +34,7 @@ */ class UuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private TimeConverterInterface $unixTimeConverter; /** * Constructs the DefaultUuidBuilder @@ -48,14 +42,18 @@ class UuidBuilder implements UuidBuilderInterface * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Uuid * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to Unix timestamps + * for converting Gregorian time extracted from version 1, 2, and 6 + * UUIDs to Unix timestamps + * @param TimeConverterInterface|null $unixTimeConverter The time converter + * to use for converter Unix Epoch time extracted from version 7 UUIDs + * to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter, + ?TimeConverterInterface $unixTimeConverter = null ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; + $this->unixTimeConverter = $unixTimeConverter ?? new UnixTimeConverter(new BrickMathCalculator()); } /** @@ -71,25 +69,34 @@ public function __construct( public function build(CodecInterface $codec, string $bytes): UuidInterface { try { + /** @var Fields $fields */ $fields = $this->buildFields($bytes); if ($fields->isNil()) { return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter); } + if ($fields->isMax()) { + return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter); + } + switch ($fields->getVersion()) { - case 1: + case Uuid::UUID_TYPE_TIME: return new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter); - case 2: + case Uuid::UUID_TYPE_DCE_SECURITY: return new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter); - case 3: + case Uuid::UUID_TYPE_HASH_MD5: return new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter); - case 4: + case Uuid::UUID_TYPE_RANDOM: return new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter); - case 5: + case Uuid::UUID_TYPE_HASH_SHA1: return new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter); - case 6: + case Uuid::UUID_TYPE_REORDERED_TIME: return new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter); + case Uuid::UUID_TYPE_UNIX_TIME: + return new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter); + case Uuid::UUID_TYPE_CUSTOM: + return new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter); } throw new UnsupportedOperationException( diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidInterface.php index 3e4d9faee..e80f33bef 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidInterface.php @@ -26,11 +26,4 @@ */ interface UuidInterface extends BaseUuidInterface { - /** - * Returns the string standard representation of the UUID as a URN - * - * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name - * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template - */ - public function getUrn(): string; } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV1.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV1.php index 764e42f84..515c038d9 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV1.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV1.php @@ -14,31 +14,25 @@ namespace Ramsey\Uuid\Rfc4122; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; -use Throwable; - -use function str_pad; - -use const STR_PAD_LEFT; /** - * Time-based, or version 1, UUIDs include timestamp, clock sequence, and node + * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node * values that are combined into a 128-bit unsigned integer * * @psalm-immutable */ final class UuidV1 extends Uuid implements UuidInterface { + use TimeTrait; + /** - * Creates a version 1 (time-based) UUID + * Creates a version 1 (Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use @@ -63,30 +57,4 @@ public function __construct( parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 1 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV2.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV2.php index 74906f050..c8ccbe422 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV2.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV2.php @@ -14,28 +14,33 @@ namespace Ramsey\Uuid\Rfc4122; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; -use Throwable; use function hexdec; -use function str_pad; - -use const STR_PAD_LEFT; /** * DCE Security version, or version 2, UUIDs include local domain identifier, * local ID for the specified domain, and node values that are combined into a * 128-bit unsigned integer * + * It is important to note that a version 2 UUID suffers from some loss of + * fidelity of the timestamp, due to replacing the time_low field with the + * local identifier. When constructing the timestamp value for date + * purposes, we replace the local identifier bits with zeros. As a result, + * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 + * minutes, 9 seconds, and 496730 microseconds). + * + * Astute observers might note this value directly corresponds to 2^32 - 1, + * or 0xffffffff. The local identifier is 32-bits, and we have set each of + * these bits to 0, so the maximum range of timestamp drift is 0x00000000 + * to 0xffffffff (counted in 100-nanosecond intervals). + * * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1 @@ -47,6 +52,8 @@ */ final class UuidV2 extends Uuid implements UuidInterface { + use TimeTrait; + /** * Creates a version 2 (DCE Security) UUID * @@ -74,41 +81,6 @@ public function __construct( parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * It is important to note that a version 2 UUID suffers from some loss of - * fidelity of the timestamp, due to replacing the time_low field with the - * local identifier. When constructing the timestamp value for date - * purposes, we replace the local identifier bits with zeros. As a result, - * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 - * minutes, 9 seconds, and 496730 microseconds). - * - * Astute observers might note this value directly corresponds to 2^32 - 1, - * or 0xffffffff. The local identifier is 32-bits, and we have set each of - * these bits to 0, so the maximum range of timestamp drift is 0x00000000 - * to 0xffffffff (counted in 100-nanosecond intervals). - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 2 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } - /** * Returns the local domain used to create this version 2 UUID */ diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV6.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV6.php new file mode 100644 index 000000000..7e3743391 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV6.php @@ -0,0 +1,29 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Nonstandard\UuidV6 as NonstandardUuidV6; + +/** + * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and + * node values that are combined into a 128-bit unsigned integer + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6 + * + * @psalm-immutable + */ +final class UuidV6 extends NonstandardUuidV6 implements UuidInterface +{ +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV7.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV7.php new file mode 100644 index 000000000..5b524c486 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV7.php @@ -0,0 +1,62 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds + * since the Unix Epoch, along with random bytes + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7 + * + * @psalm-immutable + */ +final class UuidV7 extends Uuid implements UuidInterface +{ + use TimeTrait; + + /** + * Creates a version 7 (Unix Epoch time) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_UNIX_TIME) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV7 must represent a ' + . 'version 7 (Unix Epoch time) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV8.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV8.php new file mode 100644 index 000000000..78b0290c7 --- /dev/null +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/UuidV8.php @@ -0,0 +1,65 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Version 8, Custom UUIDs provide an RFC 4122 compatible format for + * experimental or vendor-specific uses + * + * The only requirement for version 8 UUIDs is that the version and variant bits + * must be set. Otherwise, implementations are free to set the other bits + * according to their needs. As a result, the uniqueness of version 8 UUIDs is + * implementation-specific and should not be assumed. + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8 + * + * @psalm-immutable + */ +final class UuidV8 extends Uuid implements UuidInterface +{ + /** + * Creates a version 8 (custom) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_CUSTOM) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV8 must represent a ' + . 'version 8 (custom) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Validator.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Validator.php index ed43c982f..e82a11e6e 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Validator.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/Validator.php @@ -28,7 +28,7 @@ final class Validator implements ValidatorInterface { private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; + . '[1-8][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; /** * @psalm-return non-empty-string @@ -43,7 +43,8 @@ public function getPattern(): string public function validate(string $uuid): bool { $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); + $uuid = strtolower($uuid); - return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); + return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VariantTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VariantTrait.php index 4c981658f..1041de51e 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VariantTrait.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VariantTrait.php @@ -19,8 +19,8 @@ use function decbin; use function str_pad; +use function str_starts_with; use function strlen; -use function strpos; use function substr; use function unpack; @@ -58,7 +58,13 @@ public function getVariant(): int throw new InvalidBytesException('Invalid number of bytes'); } - /** @var array $parts */ + if ($this->isMax() || $this->isNil()) { + // RFC 4122 defines these special types of UUID, so we will consider + // them as belonging to the RFC 4122 variant. + return Uuid::RFC_4122; + } + + /** @var int[] $parts */ $parts = unpack('n*', $this->getBytes()); // $parts[5] is a 16-bit, unsigned integer containing the variant bits @@ -67,7 +73,7 @@ public function getVariant(): int // three characters (three most-significant bits) to determine the // variant. $binary = str_pad( - decbin((int) $parts[5]), + decbin($parts[5]), 16, '0', STR_PAD_LEFT @@ -76,15 +82,13 @@ public function getVariant(): int $msb = substr($binary, 0, 3); if ($msb === '111') { - $variant = Uuid::RESERVED_FUTURE; + return Uuid::RESERVED_FUTURE; } elseif ($msb === '110') { - $variant = Uuid::RESERVED_MICROSOFT; - } elseif (strpos($msb, '10') === 0) { - $variant = Uuid::RFC_4122; - } else { - $variant = Uuid::RESERVED_NCS; + return Uuid::RESERVED_MICROSOFT; + } elseif (str_starts_with($msb, '10')) { + return Uuid::RFC_4122; } - return $variant; + return Uuid::RESERVED_NCS; } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VersionTrait.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VersionTrait.php index cee55fbef..0195e46c7 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VersionTrait.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Rfc4122/VersionTrait.php @@ -14,6 +14,8 @@ namespace Ramsey\Uuid\Rfc4122; +use Ramsey\Uuid\Uuid; + /** * Provides common functionality for handling the version, as defined by RFC 4122 * @@ -26,6 +28,11 @@ trait VersionTrait */ abstract public function getVersion(): ?int; + /** + * Returns true if these fields represent a max UUID + */ + abstract public function isMax(): bool; + /** * Returns true if these fields represent a nil UUID */ @@ -38,20 +45,16 @@ abstract public function isNil(): bool; */ private function isCorrectVersion(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } - switch ($this->getVersion()) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - return true; - } - - return false; + return match ($this->getVersion()) { + Uuid::UUID_TYPE_TIME, Uuid::UUID_TYPE_DCE_SECURITY, + Uuid::UUID_TYPE_HASH_MD5, Uuid::UUID_TYPE_RANDOM, + Uuid::UUID_TYPE_HASH_SHA1, Uuid::UUID_TYPE_REORDERED_TIME, + Uuid::UUID_TYPE_UNIX_TIME, Uuid::UUID_TYPE_CUSTOM => true, + default => false, + }; } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Decimal.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Decimal.php index 10f93845b..acc5e754b 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Decimal.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Decimal.php @@ -19,6 +19,7 @@ use function is_numeric; use function sprintf; +use function str_starts_with; /** * A value object representing a decimal @@ -34,20 +35,10 @@ */ final class Decimal implements NumberInterface { - /** - * @var string - */ - private $value; - - /** - * @var bool - */ - private $isNegative = false; + private string $value; + private bool $isNegative = false; - /** - * @param mixed $value The decimal value to store - */ - public function __construct($value) + public function __construct(float | int | string | self $value) { $value = (string) $value; @@ -59,7 +50,7 @@ public function __construct($value) } // Remove the leading +-symbol. - if (strpos($value, '+') === 0) { + if (str_starts_with($value, '+')) { $value = substr($value, 1); } @@ -68,7 +59,7 @@ public function __construct($value) $value = '0'; } - if (strpos($value, '-') === 0) { + if (str_starts_with($value, '-')) { $this->isNegative = true; } @@ -111,18 +102,19 @@ public function __serialize(): array /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->__construct($serialized); + $this->__construct($data); } /** - * @param array{string: string} $data + * @param array{string?: string} $data + * + * @psalm-suppress UnusedMethodCall */ public function __unserialize(array $data): void { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Hexadecimal.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Hexadecimal.php index 88adc2e7e..bf71ec4b1 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Hexadecimal.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Hexadecimal.php @@ -17,10 +17,8 @@ use Ramsey\Uuid\Exception\InvalidArgumentException; use ValueError; -use function ctype_xdigit; +use function preg_match; use function sprintf; -use function strpos; -use function strtolower; use function substr; /** @@ -34,29 +32,14 @@ */ final class Hexadecimal implements TypeInterface { - /** - * @var string - */ - private $value; + private string $value; /** - * @param string $value The hexadecimal value to store + * @param self|string $value The hexadecimal value to store */ - public function __construct(string $value) + public function __construct(self | string $value) { - $value = strtolower($value); - - if (strpos($value, '0x') === 0) { - $value = substr($value, 2); - } - - if (!ctype_xdigit($value)) { - throw new InvalidArgumentException( - 'Value must be a hexadecimal number' - ); - } - - $this->value = $value; + $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } public function toString(): string @@ -90,18 +73,17 @@ public function __serialize(): array /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->__construct($serialized); + $this->__construct($data); } /** - * @param array{string: string} $data + * @param array{string?: string} $data */ public function __unserialize(array $data): void { @@ -113,4 +95,21 @@ public function __unserialize(array $data): void $this->unserialize($data['string']); } + + private function prepareValue(string $value): string + { + $value = strtolower($value); + + if (str_starts_with($value, '0x')) { + $value = substr($value, 2); + } + + if (!preg_match('/^[A-Fa-f0-9]+$/', $value)) { + throw new InvalidArgumentException( + 'Value must be a hexadecimal number' + ); + } + + return $value; + } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Integer.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Integer.php index 7690f6cd8..50dac9934 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Integer.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Integer.php @@ -17,10 +17,10 @@ use Ramsey\Uuid\Exception\InvalidArgumentException; use ValueError; -use function ctype_digit; -use function ltrim; +use function assert; +use function is_numeric; +use function preg_match; use function sprintf; -use function strpos; use function substr; /** @@ -40,52 +40,13 @@ final class Integer implements NumberInterface /** * @psalm-var numeric-string */ - private $value; + private string $value; - /** - * @var bool - */ - private $isNegative = false; + private bool $isNegative = false; - /** - * @param mixed $value The integer value to store - */ - public function __construct($value) + public function __construct(float | int | string | self $value) { - $value = (string) $value; - $sign = '+'; - - // If the value contains a sign, remove it for ctype_digit() check. - if (strpos($value, '-') === 0 || strpos($value, '+') === 0) { - $sign = substr($value, 0, 1); - $value = substr($value, 1); - } - - if (!ctype_digit($value)) { - throw new InvalidArgumentException( - 'Value must be a signed integer or a string containing only ' - . 'digits 0-9 and, optionally, a sign (+ or -)' - ); - } - - // Trim any leading zeros. - $value = ltrim($value, '0'); - - // Set to zero if the string is empty after trimming zeros. - if ($value === '') { - $value = '0'; - } - - // Add the negative sign back to the value. - if ($sign === '-' && $value !== '0') { - $value = $sign . $value; - $this->isNegative = true; - } - - /** @psalm-var numeric-string $numericValue */ - $numericValue = $value; - - $this->value = $numericValue; + $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } public function isNegative(): bool @@ -101,6 +62,9 @@ public function toString(): string return $this->value; } + /** + * @psalm-return numeric-string + */ public function __toString(): string { return $this->toString(); @@ -127,18 +91,17 @@ public function __serialize(): array /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->__construct($serialized); + $this->__construct($data); } /** - * @param array{string: string} $data + * @param array{string?: string} $data */ public function __unserialize(array $data): void { @@ -150,4 +113,46 @@ public function __unserialize(array $data): void $this->unserialize($data['string']); } + + /** + * @return numeric-string + */ + private function prepareValue(float | int | string $value): string + { + $value = (string) $value; + $sign = '+'; + + // If the value contains a sign, remove it for digit pattern check. + if (str_starts_with($value, '-') || str_starts_with($value, '+')) { + $sign = substr($value, 0, 1); + $value = substr($value, 1); + } + + if (!preg_match('/^\d+$/', $value)) { + throw new InvalidArgumentException( + 'Value must be a signed integer or a string containing only ' + . 'digits 0-9 and, optionally, a sign (+ or -)' + ); + } + + // Trim any leading zeros. + $value = ltrim($value, '0'); + + // Set to zero if the string is empty after trimming zeros. + if ($value === '') { + $value = '0'; + } + + // Add the negative sign back to the value. + if ($sign === '-' && $value !== '0') { + $value = $sign . $value; + + /** @psalm-suppress InaccessibleProperty */ + $this->isNegative = true; + } + + assert(is_numeric($value)); + + return $value; + } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Time.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Time.php index dd1b8bc28..0cedb4476 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Time.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Type/Time.php @@ -17,7 +17,6 @@ use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Type\Integer as IntegerObject; use ValueError; -use stdClass; use function json_decode; use function json_encode; @@ -34,22 +33,13 @@ */ final class Time implements TypeInterface { - /** - * @var IntegerObject - */ - private $seconds; - - /** - * @var IntegerObject - */ - private $microseconds; + private IntegerObject $seconds; + private IntegerObject $microseconds; - /** - * @param mixed $seconds - * @param mixed $microseconds - */ - public function __construct($seconds, $microseconds = 0) - { + public function __construct( + float | int | string | IntegerObject $seconds, + float | int | string | IntegerObject $microseconds = 0, + ) { $this->seconds = new IntegerObject($seconds); $this->microseconds = new IntegerObject($microseconds); } @@ -66,7 +56,7 @@ public function getMicroseconds(): IntegerObject public function toString(): string { - return $this->seconds->toString() . '.' . $this->microseconds->toString(); + return $this->seconds->toString() . '.' . sprintf('%06s', $this->microseconds->toString()); } public function __toString(): string @@ -104,27 +94,26 @@ public function __serialize(): array /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - /** @var stdClass $time */ - $time = json_decode($serialized); + /** @var array{seconds?: int|float|string, microseconds?: int|float|string} $time */ + $time = json_decode($data, true); - if (!isset($time->seconds) || !isset($time->microseconds)) { + if (!isset($time['seconds']) || !isset($time['microseconds'])) { throw new UnsupportedOperationException( 'Attempted to unserialize an invalid value' ); } - $this->__construct($time->seconds, $time->microseconds); + $this->__construct($time['seconds'], $time['microseconds']); } /** - * @param array{seconds: string, microseconds: string} $data + * @param array{seconds?: string, microseconds?: string} $data */ public function __unserialize(array $data): void { diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/Uuid.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/Uuid.php index 945480ba4..e0384a50c 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/Uuid.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/Uuid.php @@ -14,10 +14,12 @@ namespace Ramsey\Uuid; +use BadMethodCallException; use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; @@ -27,6 +29,7 @@ use function assert; use function bin2hex; +use function method_exists; use function preg_match; use function sprintf; use function str_replace; @@ -82,6 +85,14 @@ class Uuid implements UuidInterface */ public const NIL = '00000000-0000-0000-0000-000000000000'; + /** + * The max UUID is a special form of UUID that is specified to have all 128 + * bits set to one + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID + */ + public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; + /** * Variant: reserved, NCS backward compatibility * @@ -116,7 +127,7 @@ class Uuid implements UuidInterface public const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'; /** - * Version 1 (time-based) UUID + * Version 1 (Gregorian time) UUID * * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ @@ -156,15 +167,28 @@ class Uuid implements UuidInterface public const UUID_TYPE_HASH_SHA1 = 5; /** - * Version 6 (ordered-time) UUID + * @deprecated Use {@see Uuid::UUID_TYPE_REORDERED_TIME} instead. + */ + public const UUID_TYPE_PEABODY = 6; + + /** + * Version 6 (reordered time) UUID * - * This is named `UUID_TYPE_PEABODY`, since the specification is still in - * draft form, and the primary author/editor's name is Brad Peabody. + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6 + */ + public const UUID_TYPE_REORDERED_TIME = 6; + + /** + * Version 7 (Unix Epoch time) UUID * - * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft - * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7 */ - public const UUID_TYPE_PEABODY = 6; + public const UUID_TYPE_UNIX_TIME = 7; + + /** + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8 + */ + public const UUID_TYPE_CUSTOM = 8; /** * DCE Security principal domain @@ -198,38 +222,19 @@ class Uuid implements UuidInterface self::DCE_DOMAIN_ORG => 'org', ]; - /** - * @var UuidFactoryInterface|null - */ - private static $factory = null; + private static ?UuidFactoryInterface $factory = null; /** - * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations - * for the default/happy path internal scenarios + * @var bool flag to detect if the UUID factory was replaced internally, + * which disables all optimizations for the default/happy path internal + * scenarios */ - private static $factoryReplaced = false; + private static bool $factoryReplaced = false; - /** - * @var CodecInterface - */ - protected $codec; - - /** - * The fields that make up this UUID - * - * @var Rfc4122FieldsInterface - */ - protected $fields; - - /** - * @var NumberConverterInterface - */ - protected $numberConverter; - - /** - * @var TimeConverterInterface - */ - protected $timeConverter; + protected CodecInterface $codec; + protected NumberConverterInterface $numberConverter; + protected Rfc4122FieldsInterface $fields; + protected TimeConverterInterface $timeConverter; /** * Creates a universally unique identifier (UUID) from an array of fields @@ -288,7 +293,7 @@ public function jsonSerialize(): string */ public function serialize(): string { - return $this->getFields()->getBytes(); + return $this->codec->encode($this); } /** @@ -302,19 +307,17 @@ public function __serialize(): array /** * Re-constructs the object from its serialized form * - * @param string $serialized The serialized PHP string to unserialize into + * @param string $data The serialized PHP string to unserialize into * a UuidInterface instance - * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - if (strlen($serialized) === 16) { + if (strlen($data) === 16) { /** @var Uuid $uuid */ - $uuid = self::getFactory()->fromBytes($serialized); + $uuid = self::getFactory()->fromBytes($data); } else { /** @var Uuid $uuid */ - $uuid = self::getFactory()->fromString($serialized); + $uuid = self::getFactory()->fromString($data); } $this->codec = $uuid->codec; @@ -324,7 +327,7 @@ public function unserialize($serialized): void } /** - * @param array{bytes: string} $data + * @param array{bytes?: string} $data */ public function __unserialize(array $data): void { @@ -384,6 +387,11 @@ public function getInteger(): IntegerObject return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString())); } + public function getUrn(): string + { + return 'urn:uuid:' . $this->toString(); + } + /** * @psalm-return non-empty-string */ @@ -438,20 +446,20 @@ public static function setFactory(UuidFactoryInterface $factory): void */ public static function fromBytes(string $bytes): UuidInterface { - if (! self::$factoryReplaced && strlen($bytes) === 16) { + if (!self::$factoryReplaced && strlen($bytes) === 16) { $base16Uuid = bin2hex($bytes); // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID return self::fromString( substr($base16Uuid, 0, 8) - . '-' - . substr($base16Uuid, 8, 4) - . '-' - . substr($base16Uuid, 12, 4) - . '-' - . substr($base16Uuid, 16, 4) - . '-' - . substr($base16Uuid, 20, 12) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) ); } @@ -476,10 +484,11 @@ public static function fromBytes(string $bytes): UuidInterface */ public static function fromString(string $uuid): UuidInterface { - if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { + $uuid = strtolower($uuid); + if (!self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { assert($uuid !== ''); - return new LazyUuidFromString(strtolower($uuid)); + return new LazyUuidFromString($uuid); } return self::getFactory()->fromString($uuid); @@ -506,6 +515,33 @@ public static function fromDateTime( return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq); } + /** + * Creates a UUID from the Hexadecimal object + * + * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number + * + * @return UuidInterface A UuidInterface instance created from the Hexadecimal + * object representing a hexadecimal number + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners + * @psalm-suppress MixedInferredReturnType,MixedReturnStatement + */ + public static function fromHexadecimal(Hexadecimal $hex): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'fromHexadecimal')) { + /** + * @phpstan-ignore-next-line + * @psalm-suppress UndefinedInterfaceMethod + */ + return self::getFactory()->fromHexadecimal($hex); + } + + throw new BadMethodCallException('The method fromHexadecimal() does not exist on the provided factory'); + } + /** * Creates a UUID from a 128-bit integer string * @@ -519,6 +555,7 @@ public static function fromDateTime( */ public static function fromInteger(string $integer): UuidInterface { + /** @psalm-suppress ImpureMethodCall */ return self::getFactory()->fromInteger($integer); } @@ -531,20 +568,23 @@ public static function fromInteger(string $integer): UuidInterface * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners + * + * @psalm-assert-if-true =non-empty-string $uuid */ public static function isValid(string $uuid): bool { + /** @psalm-suppress ImpureMethodCall */ return self::getFactory()->getValidator()->validate($uuid); } /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the * hardware address; this number may be represented as an integer or a * hexadecimal string - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -643,12 +683,12 @@ public static function uuid5($ns, string $name): UuidInterface } /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware * address - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -661,4 +701,58 @@ public static function uuid6( ): UuidInterface { return self::getFactory()->uuid6($node, $clockSeq); } + + /** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 7 UUID + */ + public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'uuid7')) { + /** @var UuidInterface */ + return $factory->uuid7($dateTime); + } + + throw new UnsupportedOperationException( + 'The provided factory does not support the uuid7() method', + ); + } + + /** + * Returns a version 8 (custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 8 UUID + */ + public static function uuid8(string $bytes): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'uuid8')) { + /** @var UuidInterface */ + return $factory->uuid8($bytes); + } + + throw new UnsupportedOperationException( + 'The provided factory does not support the uuid8() method', + ); + } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactory.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactory.php index 6f2cea061..1b06ea6ed 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactory.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactory.php @@ -24,6 +24,7 @@ use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; +use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; @@ -45,61 +46,26 @@ class UuidFactory implements UuidFactoryInterface { - /** - * @var CodecInterface - */ - private $codec; - - /** - * @var DceSecurityGeneratorInterface - */ - private $dceSecurityGenerator; - - /** - * @var NameGeneratorInterface - */ - private $nameGenerator; - - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private CodecInterface $codec; + private DceSecurityGeneratorInterface $dceSecurityGenerator; + private NameGeneratorInterface $nameGenerator; + private NodeProviderInterface $nodeProvider; + private NumberConverterInterface $numberConverter; + private RandomGeneratorInterface $randomGenerator; + private TimeConverterInterface $timeConverter; + private TimeGeneratorInterface $timeGenerator; + private TimeGeneratorInterface $unixTimeGenerator; + private UuidBuilderInterface $uuidBuilder; + private ValidatorInterface $validator; /** - * @var TimeGeneratorInterface + * @var bool whether the feature set was provided from outside, or we can + * operate under "default" assumptions */ - private $timeGenerator; + private bool $isDefaultFeatureSet; /** - * @var UuidBuilderInterface - */ - private $uuidBuilder; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ - private $isDefaultFeatureSet; - - /** - * @param FeatureSet $features A set of available features in the current environment + * @param FeatureSet|null $features A set of available features in the current environment */ public function __construct(?FeatureSet $features = null) { @@ -117,6 +83,7 @@ public function __construct(?FeatureSet $features = null) $this->timeGenerator = $features->getTimeGenerator(); $this->uuidBuilder = $features->getBuilder(); $this->validator = $features->getValidator(); + $this->unixTimeGenerator = $features->getUnixTimeGenerator(); } /** @@ -342,7 +309,15 @@ public function fromDateTime( $bytes = $timeGenerator->generate($nodeHex, $clockSeq); - return $this->uuidFromBytesAndVersion($bytes, 1); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); + } + + /** + * @psalm-pure + */ + public function fromHexadecimal(Hexadecimal $hex): UuidInterface + { + return $this->codec->decode($hex->__toString()); } /** @@ -352,7 +327,7 @@ public function uuid1($node = null, ?int $clockSeq = null): UuidInterface { $bytes = $this->timeGenerator->generate($node, $clockSeq); - return $this->uuidFromBytesAndVersion($bytes, 1); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); } public function uuid2( @@ -368,7 +343,7 @@ public function uuid2( $clockSeq ); - return $this->uuidFromBytesAndVersion($bytes, 2); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_DCE_SECURITY); } /** @@ -377,14 +352,14 @@ public function uuid2( */ public function uuid3($ns, string $name): UuidInterface { - return $this->uuidFromNsAndName($ns, $name, 3, 'md5'); + return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_MD5, 'md5'); } public function uuid4(): UuidInterface { $bytes = $this->randomGenerator->generate(16); - return $this->uuidFromBytesAndVersion($bytes, 4); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_RANDOM); } /** @@ -393,7 +368,7 @@ public function uuid4(): UuidInterface */ public function uuid5($ns, string $name): UuidInterface { - return $this->uuidFromNsAndName($ns, $name, 5, 'sha1'); + return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_SHA1, 'sha1'); } public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface @@ -412,7 +387,46 @@ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInt $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3)); $v6Bytes .= substr($bytes, 8); - return $this->uuidFromBytesAndVersion($v6Bytes, 6); + return $this->uuidFromBytesAndVersion($v6Bytes, Uuid::UUID_TYPE_REORDERED_TIME); + } + + /** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 7 UUID + */ + public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface + { + assert($this->unixTimeGenerator instanceof UnixTimeGenerator); + $bytes = $this->unixTimeGenerator->generate(null, null, $dateTime); + + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_UNIX_TIME); + } + + /** + * Returns a version 8 (Custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 8 UUID + */ + public function uuid8(string $bytes): UuidInterface + { + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_CUSTOM); } /** @@ -430,6 +444,7 @@ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInt */ public function uuid(string $bytes): UuidInterface { + /** @psalm-suppress ImpurePropertyFetch */ return $this->uuidBuilder->build($this->codec, $bytes); } @@ -447,8 +462,12 @@ public function uuid(string $bytes): UuidInterface * * @psalm-pure */ - private function uuidFromNsAndName($ns, string $name, int $version, string $hashAlgorithm): UuidInterface - { + private function uuidFromNsAndName( + UuidInterface | string $ns, + string $name, + int $version, + string $hashAlgorithm + ): UuidInterface { if (!($ns instanceof UuidInterface)) { $ns = $this->fromString($ns); } @@ -488,6 +507,7 @@ private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInter return LazyUuidFromString::fromBytes($bytes); } + /** @psalm-suppress ImpureVariable */ return $this->uuid($bytes); } } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactoryInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactoryInterface.php index 468cc6377..d99fc9d58 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactoryInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidFactoryInterface.php @@ -25,6 +25,61 @@ */ interface UuidFactoryInterface { + /** + * Creates a UUID from a byte string + * + * @param string $bytes A binary string + * + * @return UuidInterface A UuidInterface instance created from a binary + * string representation + * + * @psalm-pure + */ + public function fromBytes(string $bytes): UuidInterface; + + /** + * Creates a UUID from a DateTimeInterface instance + * + * @param DateTimeInterface $dateTime The date and time + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID created from a DateTimeInterface instance + */ + public function fromDateTime( + DateTimeInterface $dateTime, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface; + + /** + * Creates a UUID from a 128-bit integer string + * + * @param string $integer String representation of 128-bit integer + * + * @return UuidInterface A UuidInterface instance created from the string + * representation of a 128-bit integer + * + * @psalm-pure + */ + public function fromInteger(string $integer): UuidInterface; + + /** + * Creates a UUID from the string standard representation + * + * @param string $uuid A hexadecimal string + * + * @return UuidInterface A UuidInterface instance created from a hexadecimal + * string representation + * + * @psalm-pure + */ + public function fromString(string $uuid): UuidInterface; + /** * Returns the validator to use for the factory * @@ -33,7 +88,7 @@ interface UuidFactoryInterface public function getValidator(): ValidatorInterface; /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the @@ -111,7 +166,7 @@ public function uuid4(): UuidInterface; public function uuid5($ns, string $name): UuidInterface; /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware @@ -124,59 +179,4 @@ public function uuid5($ns, string $name): UuidInterface; * version 6 UUID */ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface; - - /** - * Creates a UUID from a byte string - * - * @param string $bytes A binary string - * - * @return UuidInterface A UuidInterface instance created from a binary - * string representation - * - * @psalm-pure - */ - public function fromBytes(string $bytes): UuidInterface; - - /** - * Creates a UUID from the string standard representation - * - * @param string $uuid A hexadecimal string - * - * @return UuidInterface A UuidInterface instance created from a hexadecimal - * string representation - * - * @psalm-pure - */ - public function fromString(string $uuid): UuidInterface; - - /** - * Creates a UUID from a 128-bit integer string - * - * @param string $integer String representation of 128-bit integer - * - * @return UuidInterface A UuidInterface instance created from the string - * representation of a 128-bit integer - * - * @psalm-pure - */ - public function fromInteger(string $integer): UuidInterface; - - /** - * Creates a UUID from a DateTimeInterface instance - * - * @param DateTimeInterface $dateTime The date and time - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int|null $clockSeq A 14-bit number used to help avoid duplicates - * that could arise when the clock is set backwards in time or if the - * node ID changes - * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID created from a DateTimeInterface instance - */ - public function fromDateTime( - DateTimeInterface $dateTime, - ?Hexadecimal $node = null, - ?int $clockSeq = null - ): UuidInterface; } diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidInterface.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidInterface.php index f22eb0f99..0a9780805 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidInterface.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/UuidInterface.php @@ -19,6 +19,7 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Serializable; +use Stringable; /** * A UUID is a universally unique identifier adhering to an agreed-upon @@ -29,7 +30,8 @@ interface UuidInterface extends DeprecatedUuidInterface, JsonSerializable, - Serializable + Serializable, + Stringable { /** * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than @@ -83,6 +85,14 @@ public function getHex(): Hexadecimal; */ public function getInteger(): IntegerObject; + /** + * Returns the string standard representation of the UUID as a URN + * + * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name + * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template + */ + public function getUrn(): string; + /** * Returns the string standard representation of the UUID * diff --git a/lam/lib/3rdParty/composer/ramsey/uuid/src/functions.php b/lam/lib/3rdParty/composer/ramsey/uuid/src/functions.php index f5df1488d..1b3ce00f7 100644 --- a/lam/lib/3rdParty/composer/ramsey/uuid/src/functions.php +++ b/lam/lib/3rdParty/composer/ramsey/uuid/src/functions.php @@ -15,17 +15,18 @@ namespace Ramsey\Uuid; +use DateTimeInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the * hardware address; this number may be represented as an integer or a * hexadecimal string - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -106,12 +107,12 @@ function v5($ns, string $name): string } /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware * address - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -121,3 +122,37 @@ function v6(?Hexadecimal $node = null, ?int $clockSeq = null): string { return Uuid::uuid6($node, $clockSeq)->toString(); } + +/** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return non-empty-string Version 7 UUID as a string + */ +function v7(?DateTimeInterface $dateTime = null): string +{ + return Uuid::uuid7($dateTime)->toString(); +} + +/** + * Returns a version 8 (custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return non-empty-string Version 8 UUID as a string + */ +function v8(string $bytes): string +{ + return Uuid::uuid8($bytes)->toString(); +} diff --git a/lam/lib/3rdParty/composer/symfony/deprecation-contracts/composer.json b/lam/lib/3rdParty/composer/symfony/deprecation-contracts/composer.json index cc7cc1237..1c1b4ba0e 100644 --- a/lam/lib/3rdParty/composer/symfony/deprecation-contracts/composer.json +++ b/lam/lib/3rdParty/composer/symfony/deprecation-contracts/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "autoload": { "files": [ @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lam/lib/3rdParty/composer/symfony/deprecation-contracts/function.php b/lam/lib/3rdParty/composer/symfony/deprecation-contracts/function.php index d4371504a..2d56512ba 100644 --- a/lam/lib/3rdParty/composer/symfony/deprecation-contracts/function.php +++ b/lam/lib/3rdParty/composer/symfony/deprecation-contracts/function.php @@ -20,7 +20,7 @@ * * @author Nicolas Grekas */ - function trigger_deprecation(string $package, string $version, string $message, ...$args): void + function trigger_deprecation(string $package, string $version, string $message, mixed ...$args): void { @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED); } diff --git a/lam/lib/3rdParty/composer/symfony/http-client/Response/TraceableResponse.php b/lam/lib/3rdParty/composer/symfony/http-client/Response/TraceableResponse.php index d656c0a5f..3bf1571fd 100644 --- a/lam/lib/3rdParty/composer/symfony/http-client/Response/TraceableResponse.php +++ b/lam/lib/3rdParty/composer/symfony/http-client/Response/TraceableResponse.php @@ -57,7 +57,9 @@ public function __wakeup() public function __destruct() { try { - $this->response->__destruct(); + if (method_exists($this->response, '__destruct')) { + $this->response->__destruct(); + } } finally { if ($this->event && $this->event->isStarted()) { $this->event->stop(); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeader.php b/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeader.php index 057c6b530..b15ba61d4 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeader.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeader.php @@ -27,12 +27,9 @@ class AcceptHeader /** * @var AcceptHeaderItem[] */ - private $items = []; + private array $items = []; - /** - * @var bool - */ - private $sorted = true; + private bool $sorted = true; /** * @param AcceptHeaderItem[] $items @@ -46,10 +43,8 @@ public function __construct(array $items) /** * Builds an AcceptHeader instance from a string. - * - * @return self */ - public static function fromString(?string $headerValue) + public static function fromString(?string $headerValue): self { $index = 0; @@ -68,30 +63,24 @@ public static function fromString(?string $headerValue) /** * Returns header value's string representation. - * - * @return string */ - public function __toString() + public function __toString(): string { return implode(',', $this->items); } /** * Tests if header has given value. - * - * @return bool */ - public function has(string $value) + public function has(string $value): bool { return isset($this->items[$value]); } /** * Returns given value's item, if exists. - * - * @return AcceptHeaderItem|null */ - public function get(string $value) + public function get(string $value): ?AcceptHeaderItem { return $this->items[$value] ?? $this->items[explode('/', $value)[0].'/*'] ?? $this->items['*/*'] ?? $this->items['*'] ?? null; } @@ -101,7 +90,7 @@ public function get(string $value) * * @return $this */ - public function add(AcceptHeaderItem $item) + public function add(AcceptHeaderItem $item): static { $this->items[$item->getValue()] = $item; $this->sorted = false; @@ -114,7 +103,7 @@ public function add(AcceptHeaderItem $item) * * @return AcceptHeaderItem[] */ - public function all() + public function all(): array { $this->sort(); @@ -123,10 +112,8 @@ public function all() /** * Filters items on their value using given regex. - * - * @return self */ - public function filter(string $pattern) + public function filter(string $pattern): self { return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) { return preg_match($pattern, $item->getValue()); @@ -135,10 +122,8 @@ public function filter(string $pattern) /** * Returns first item. - * - * @return AcceptHeaderItem|null */ - public function first() + public function first(): ?AcceptHeaderItem { $this->sort(); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeaderItem.php b/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeaderItem.php index bc4014e58..35ecd4ea2 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeaderItem.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/AcceptHeaderItem.php @@ -18,10 +18,10 @@ */ class AcceptHeaderItem { - private $value; - private $quality = 1.0; - private $index = 0; - private $attributes = []; + private string $value; + private float $quality = 1.0; + private int $index = 0; + private array $attributes = []; public function __construct(string $value, array $attributes = []) { @@ -33,10 +33,8 @@ public function __construct(string $value, array $attributes = []) /** * Builds an AcceptHeaderInstance instance from a string. - * - * @return self */ - public static function fromString(?string $itemValue) + public static function fromString(?string $itemValue): self { $parts = HeaderUtils::split($itemValue ?? '', ';='); @@ -48,10 +46,8 @@ public static function fromString(?string $itemValue) /** * Returns header value's string representation. - * - * @return string */ - public function __toString() + public function __toString(): string { $string = $this->value.($this->quality < 1 ? ';q='.$this->quality : ''); if (\count($this->attributes) > 0) { @@ -66,7 +62,7 @@ public function __toString() * * @return $this */ - public function setValue(string $value) + public function setValue(string $value): static { $this->value = $value; @@ -75,10 +71,8 @@ public function setValue(string $value) /** * Returns the item value. - * - * @return string */ - public function getValue() + public function getValue(): string { return $this->value; } @@ -88,7 +82,7 @@ public function getValue() * * @return $this */ - public function setQuality(float $quality) + public function setQuality(float $quality): static { $this->quality = $quality; @@ -97,10 +91,8 @@ public function setQuality(float $quality) /** * Returns the item quality. - * - * @return float */ - public function getQuality() + public function getQuality(): float { return $this->quality; } @@ -110,7 +102,7 @@ public function getQuality() * * @return $this */ - public function setIndex(int $index) + public function setIndex(int $index): static { $this->index = $index; @@ -119,42 +111,32 @@ public function setIndex(int $index) /** * Returns the item index. - * - * @return int */ - public function getIndex() + public function getIndex(): int { return $this->index; } /** * Tests if an attribute exists. - * - * @return bool */ - public function hasAttribute(string $name) + public function hasAttribute(string $name): bool { return isset($this->attributes[$name]); } /** * Returns an attribute by its name. - * - * @param mixed $default - * - * @return mixed */ - public function getAttribute(string $name, $default = null) + public function getAttribute(string $name, mixed $default = null): mixed { - return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; + return $this->attributes[$name] ?? $default; } /** * Returns all attributes. - * - * @return array */ - public function getAttributes() + public function getAttributes(): array { return $this->attributes; } @@ -164,7 +146,7 @@ public function getAttributes() * * @return $this */ - public function setAttribute(string $name, string $value) + public function setAttribute(string $name, string $value): static { if ('q' === $name) { $this->quality = (float) $value; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/BinaryFileResponse.php b/lam/lib/3rdParty/composer/symfony/http-foundation/BinaryFileResponse.php index 30eff944d..8990c9111 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/BinaryFileResponse.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/BinaryFileResponse.php @@ -34,6 +34,7 @@ class BinaryFileResponse extends Response protected $offset = 0; protected $maxlen = -1; protected $deleteFileAfterSend = false; + protected $chunkSize = 8 * 1024; /** * @param \SplFileInfo|string $file The file to stream @@ -44,7 +45,7 @@ class BinaryFileResponse extends Response * @param bool $autoEtag Whether the ETag header should be automatically set * @param bool $autoLastModified Whether the Last-Modified header should be automatically set */ - public function __construct($file, int $status = 200, array $headers = [], bool $public = true, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true) + public function __construct(\SplFileInfo|string $file, int $status = 200, array $headers = [], bool $public = true, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true) { parent::__construct(null, $status, $headers); @@ -55,32 +56,14 @@ public function __construct($file, int $status = 200, array $headers = [], bool } } - /** - * @param \SplFileInfo|string $file The file to stream - * @param int $status The response status code - * @param array $headers An array of response headers - * @param bool $public Files are public by default - * @param string|null $contentDisposition The type of Content-Disposition to set automatically with the filename - * @param bool $autoEtag Whether the ETag header should be automatically set - * @param bool $autoLastModified Whether the Last-Modified header should be automatically set - * - * @return static - */ - public static function create($file = null, int $status = 200, array $headers = [], bool $public = true, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true) - { - return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified); - } - /** * Sets the file to stream. * - * @param \SplFileInfo|string $file The file to stream - * * @return $this * * @throws FileException */ - public function setFile($file, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true) + public function setFile(\SplFileInfo|string $file, string $contentDisposition = null, bool $autoEtag = false, bool $autoLastModified = true): static { if (!$file instanceof File) { if ($file instanceof \SplFileInfo) { @@ -113,18 +96,34 @@ public function setFile($file, string $contentDisposition = null, bool $autoEtag /** * Gets the file. - * - * @return File The file to stream */ - public function getFile() + public function getFile(): File { return $this->file; } + /** + * Sets the response stream chunk size. + * + * @return $this + */ + public function setChunkSize(int $chunkSize): static + { + if ($chunkSize < 1 || $chunkSize > \PHP_INT_MAX) { + throw new \LogicException('The chunk size of a BinaryFileResponse cannot be less than 1 or greater than PHP_INT_MAX.'); + } + + $this->chunkSize = $chunkSize; + + return $this; + } + /** * Automatically sets the Last-Modified header according the file modification date. + * + * @return $this */ - public function setAutoLastModified() + public function setAutoLastModified(): static { $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime())); @@ -133,8 +132,10 @@ public function setAutoLastModified() /** * Automatically sets the ETag header according to the checksum of the file. + * + * @return $this */ - public function setAutoEtag() + public function setAutoEtag(): static { $this->setEtag(base64_encode(hash_file('sha256', $this->file->getPathname(), true))); @@ -150,13 +151,13 @@ public function setAutoEtag() * * @return $this */ - public function setContentDisposition(string $disposition, string $filename = '', string $filenameFallback = '') + public function setContentDisposition(string $disposition, string $filename = '', string $filenameFallback = ''): static { if ('' === $filename) { $filename = $this->file->getFilename(); } - if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) { + if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || str_contains($filename, '%'))) { $encoding = mb_detect_encoding($filename, null, true) ?: '8bit'; for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) { @@ -179,17 +180,21 @@ public function setContentDisposition(string $disposition, string $filename = '' /** * {@inheritdoc} */ - public function prepare(Request $request) + public function prepare(Request $request): static { - if (!$this->headers->has('Content-Type')) { - $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream'); + if ($this->isInformational() || $this->isEmpty()) { + parent::prepare($request); + + $this->maxlen = 0; + + return $this; } - if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) { - $this->setProtocolVersion('1.1'); + if (!$this->headers->has('Content-Type')) { + $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream'); } - $this->ensureIEOverSSLCompatibility($request); + parent::prepare($request); $this->offset = 0; $this->maxlen = -1; @@ -197,6 +202,7 @@ public function prepare(Request $request) if (false === $fileSize = $this->file->getSize()) { return $this; } + $this->headers->remove('Transfer-Encoding'); $this->headers->set('Content-Length', $fileSize); if (!$this->headers->has('Accept-Ranges')) { @@ -217,7 +223,7 @@ public function prepare(Request $request) // @link https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-redirect $parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping', ''), ',='); foreach ($parts as $part) { - list($pathPrefix, $location) = $part; + [$pathPrefix, $location] = $part; if (substr($path, 0, \strlen($pathPrefix)) === $pathPrefix) { $path = $location.substr($path, \strlen($pathPrefix)); // Only set X-Accel-Redirect header if a valid URI can be produced @@ -231,38 +237,45 @@ public function prepare(Request $request) $this->headers->set($type, $path); $this->maxlen = 0; } - } elseif ($request->headers->has('Range')) { + } elseif ($request->headers->has('Range') && $request->isMethod('GET')) { // Process the range headers. if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) { $range = $request->headers->get('Range'); - list($start, $end) = explode('-', substr($range, 6), 2) + [0]; + if (str_starts_with($range, 'bytes=')) { + [$start, $end] = explode('-', substr($range, 6), 2) + [0]; - $end = ('' === $end) ? $fileSize - 1 : (int) $end; + $end = ('' === $end) ? $fileSize - 1 : (int) $end; - if ('' === $start) { - $start = $fileSize - $end; - $end = $fileSize - 1; - } else { - $start = (int) $start; - } + if ('' === $start) { + $start = $fileSize - $end; + $end = $fileSize - 1; + } else { + $start = (int) $start; + } - if ($start <= $end) { - if ($start < 0 || $end > $fileSize - 1) { - $this->setStatusCode(416); - $this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize)); - } elseif (0 !== $start || $end !== $fileSize - 1) { - $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1; - $this->offset = $start; - - $this->setStatusCode(206); - $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize)); - $this->headers->set('Content-Length', $end - $start + 1); + if ($start <= $end) { + $end = min($end, $fileSize - 1); + if ($start < 0 || $start > $end) { + $this->setStatusCode(416); + $this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize)); + } elseif ($end - $start < $fileSize - 1) { + $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1; + $this->offset = $start; + + $this->setStatusCode(206); + $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize)); + $this->headers->set('Content-Length', $end - $start + 1); + } } } } } + if ($request->isMethod('HEAD')) { + $this->maxlen = 0; + } + return $this; } @@ -280,30 +293,46 @@ private function hasValidIfRangeHeader(?string $header): bool } /** - * Sends the file. - * * {@inheritdoc} */ - public function sendContent() + public function sendContent(): static { - if (!$this->isSuccessful()) { - return parent::sendContent(); - } + try { + if (!$this->isSuccessful()) { + return parent::sendContent(); + } - if (0 === $this->maxlen) { - return $this; - } + if (0 === $this->maxlen) { + return $this; + } - $out = fopen('php://output', 'wb'); - $file = fopen($this->file->getPathname(), 'rb'); + $out = fopen('php://output', 'w'); + $file = fopen($this->file->getPathname(), 'r'); - stream_copy_to_stream($file, $out, $this->maxlen, $this->offset); + ignore_user_abort(true); - fclose($out); - fclose($file); + if (0 !== $this->offset) { + fseek($file, $this->offset); + } - if ($this->deleteFileAfterSend && file_exists($this->file->getPathname())) { - unlink($this->file->getPathname()); + $length = $this->maxlen; + while ($length && !feof($file)) { + $read = ($length > $this->chunkSize) ? $this->chunkSize : $length; + $length -= $read; + + stream_copy_to_stream($file, $out, $read); + + if (connection_aborted()) { + break; + } + } + + fclose($out); + fclose($file); + } finally { + if ($this->deleteFileAfterSend && is_file($this->file->getPathname())) { + unlink($this->file->getPathname()); + } } return $this; @@ -314,7 +343,7 @@ public function sendContent() * * @throws \LogicException when the content is not null */ - public function setContent(?string $content) + public function setContent(?string $content): static { if (null !== $content) { throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.'); @@ -326,7 +355,7 @@ public function setContent(?string $content) /** * {@inheritdoc} */ - public function getContent() + public function getContent(): string|false { return false; } @@ -345,7 +374,7 @@ public static function trustXSendfileTypeHeader() * * @return $this */ - public function deleteFileAfterSend(bool $shouldDelete = true) + public function deleteFileAfterSend(bool $shouldDelete = true): static { $this->deleteFileAfterSend = $shouldDelete; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/CHANGELOG.md b/lam/lib/3rdParty/composer/symfony/http-foundation/CHANGELOG.md index 0af7d000a..b528419d3 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/CHANGELOG.md @@ -1,6 +1,73 @@ CHANGELOG ========= +6.0 +--- + + * Remove the `NamespacedAttributeBag` class + * Removed `Response::create()`, `JsonResponse::create()`, + `RedirectResponse::create()`, `StreamedResponse::create()` and + `BinaryFileResponse::create()` methods (use `__construct()` instead) + * Not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()` throws an `\InvalidArgumentException`; wrap your filter in a closure instead + * Not passing a `Closure` together with `FILTER_CALLBACK` to `InputBag::filter()` throws an `\InvalidArgumentException`; wrap your filter in a closure instead + * Removed the `Request::HEADER_X_FORWARDED_ALL` constant, use either `Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO` or `Request::HEADER_X_FORWARDED_AWS_ELB` or `Request::HEADER_X_FORWARDED_TRAEFIK`constants instead + * Rename `RequestStack::getMasterRequest()` to `getMainRequest()` + * Not passing `FILTER_REQUIRE_ARRAY` or `FILTER_FORCE_ARRAY` flags to `InputBag::filter()` when filtering an array will throw `BadRequestException` + * Removed the `Request::HEADER_X_FORWARDED_ALL` constant + * Retrieving non-scalar values using `InputBag::get()` will throw `BadRequestException` (use `InputBad::all()` instead to retrieve an array) + * Passing non-scalar default value as the second argument `InputBag::get()` will throw `\InvalidArgumentException` + * Passing non-scalar, non-array value as the second argument `InputBag::set()` will throw `\InvalidArgumentException` + * Passing `null` as `$requestIp` to `IpUtils::__checkIp()`, `IpUtils::__checkIp4()` or `IpUtils::__checkIp6()` is not supported anymore. + +5.4 +--- + + * Deprecate passing `null` as `$requestIp` to `IpUtils::__checkIp()`, `IpUtils::__checkIp4()` or `IpUtils::__checkIp6()`, pass an empty string instead. + * Add the `litespeed_finish_request` method to work with Litespeed + * Deprecate `upload_progress.*` and `url_rewriter.tags` session options + * Allow setting session options via DSN + +5.3 +--- + + * Add the `SessionFactory`, `NativeSessionStorageFactory`, `PhpBridgeSessionStorageFactory` and `MockFileSessionStorageFactory` classes + * Calling `Request::getSession()` when there is no available session throws a `SessionNotFoundException` + * Add the `RequestStack::getSession` method + * Deprecate the `NamespacedAttributeBag` class + * Add `ResponseFormatSame` PHPUnit constraint + * Deprecate the `RequestStack::getMasterRequest()` method and add `getMainRequest()` as replacement + +5.2.0 +----- + + * added support for `X-Forwarded-Prefix` header + * added `HeaderUtils::parseQuery()`: it does the same as `parse_str()` but preserves dots in variable names + * added `File::getContent()` + * added ability to use comma separated ip addresses for `RequestMatcher::matchIps()` + * added `Request::toArray()` to parse a JSON request body to an array + * added `RateLimiter\RequestRateLimiterInterface` and `RateLimiter\AbstractRequestRateLimiter` + * deprecated not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()`; wrap your filter in a closure instead. + * Deprecated the `Request::HEADER_X_FORWARDED_ALL` constant, use either `HEADER_X_FORWARDED_FOR | HEADER_X_FORWARDED_HOST | HEADER_X_FORWARDED_PORT | HEADER_X_FORWARDED_PROTO` or `HEADER_X_FORWARDED_AWS_ELB` or `HEADER_X_FORWARDED_TRAEFIK` constants instead. + * Deprecated `BinaryFileResponse::create()`, use `__construct()` instead + +5.1.0 +----- + + * added `Cookie::withValue`, `Cookie::withDomain`, `Cookie::withExpires`, + `Cookie::withPath`, `Cookie::withSecure`, `Cookie::withHttpOnly`, + `Cookie::withRaw`, `Cookie::withSameSite` + * Deprecate `Response::create()`, `JsonResponse::create()`, + `RedirectResponse::create()`, and `StreamedResponse::create()` methods (use + `__construct()` instead) + * added `Request::preferSafeContent()` and `Response::setContentSafe()` to handle "safe" HTTP preference + according to [RFC 8674](https://tools.ietf.org/html/rfc8674) + * made the Mime component an optional dependency + * added `MarshallingSessionHandler`, `IdentityMarshaller` + * made `Session` accept a callback to report when the session is being used + * Add support for all core cache control directives + * Added `Symfony\Component\HttpFoundation\InputBag` + * Deprecated retrieving non-string values using `InputBag::get()`, use `InputBag::all()` if you need access to the collection of values + 5.0.0 ----- diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Cookie.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Cookie.php index fc711ee66..fb2853046 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Cookie.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Cookie.php @@ -18,9 +18,9 @@ */ class Cookie { - const SAMESITE_NONE = 'none'; - const SAMESITE_LAX = 'lax'; - const SAMESITE_STRICT = 'strict'; + public const SAMESITE_NONE = 'none'; + public const SAMESITE_LAX = 'lax'; + public const SAMESITE_STRICT = 'strict'; protected $name; protected $value; @@ -30,20 +30,18 @@ class Cookie protected $secure; protected $httpOnly; - private $raw; - private $sameSite; - private $secureDefault = false; + private bool $raw; + private ?string $sameSite = null; + private bool $secureDefault = false; - private static $reservedCharsList = "=,; \t\r\n\v\f"; - private static $reservedCharsFrom = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"]; - private static $reservedCharsTo = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C']; + private const RESERVED_CHARS_LIST = "=,; \t\r\n\v\f"; + private const RESERVED_CHARS_FROM = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"]; + private const RESERVED_CHARS_TO = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C']; /** * Creates cookie from raw header string. - * - * @return static */ - public static function fromString(string $cookie, bool $decode = false) + public static function fromString(string $cookie, bool $decode = false): static { $data = [ 'expires' => 0, @@ -62,15 +60,16 @@ public static function fromString(string $cookie, bool $decode = false) $value = isset($part[1]) ? ($decode ? urldecode($part[1]) : $part[1]) : null; $data = HeaderUtils::combine($parts) + $data; + $data['expires'] = self::expiresTimestamp($data['expires']); - if (isset($data['max-age'])) { + if (isset($data['max-age']) && ($data['max-age'] > 0 || $data['expires'] > time())) { $data['expires'] = time() + (int) $data['max-age']; } return new static($name, $value, $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']); } - public static function create(string $name, string $value = null, $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = self::SAMESITE_LAX): self + public static function create(string $name, string $value = null, int|string|\DateTimeInterface $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = self::SAMESITE_LAX): self { return new self($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite); } @@ -88,10 +87,10 @@ public static function create(string $name, string $value = null, $expire = 0, ? * * @throws \InvalidArgumentException */ - public function __construct(string $name, string $value = null, $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = 'lax') + public function __construct(string $name, string $value = null, int|string|\DateTimeInterface $expire = 0, ?string $path = '/', string $domain = null, bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = 'lax') { // from PHP source code - if ($raw && false !== strpbrk($name, self::$reservedCharsList)) { + if ($raw && false !== strpbrk($name, self::RESERVED_CHARS_LIST)) { throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name)); } @@ -99,6 +98,55 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st throw new \InvalidArgumentException('The cookie name cannot be empty.'); } + $this->name = $name; + $this->value = $value; + $this->domain = $domain; + $this->expire = self::expiresTimestamp($expire); + $this->path = empty($path) ? '/' : $path; + $this->secure = $secure; + $this->httpOnly = $httpOnly; + $this->raw = $raw; + $this->sameSite = $this->withSameSite($sameSite)->sameSite; + } + + /** + * Creates a cookie copy with a new value. + */ + public function withValue(?string $value): static + { + $cookie = clone $this; + $cookie->value = $value; + + return $cookie; + } + + /** + * Creates a cookie copy with a new domain that the cookie is available to. + */ + public function withDomain(?string $domain): static + { + $cookie = clone $this; + $cookie->domain = $domain; + + return $cookie; + } + + /** + * Creates a cookie copy with a new time the cookie expires. + */ + public function withExpires(int|string|\DateTimeInterface $expire = 0): static + { + $cookie = clone $this; + $cookie->expire = self::expiresTimestamp($expire); + + return $cookie; + } + + /** + * Converts expires formats to a unix timestamp. + */ + private static function expiresTimestamp(int|string|\DateTimeInterface $expire = 0): int + { // convert expiration time to a Unix timestamp if ($expire instanceof \DateTimeInterface) { $expire = $expire->format('U'); @@ -110,15 +158,62 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st } } - $this->name = $name; - $this->value = $value; - $this->domain = $domain; - $this->expire = 0 < $expire ? (int) $expire : 0; - $this->path = empty($path) ? '/' : $path; - $this->secure = $secure; - $this->httpOnly = $httpOnly; - $this->raw = $raw; + return 0 < $expire ? (int) $expire : 0; + } + /** + * Creates a cookie copy with a new path on the server in which the cookie will be available on. + */ + public function withPath(string $path): static + { + $cookie = clone $this; + $cookie->path = '' === $path ? '/' : $path; + + return $cookie; + } + + /** + * Creates a cookie copy that only be transmitted over a secure HTTPS connection from the client. + */ + public function withSecure(bool $secure = true): static + { + $cookie = clone $this; + $cookie->secure = $secure; + + return $cookie; + } + + /** + * Creates a cookie copy that be accessible only through the HTTP protocol. + */ + public function withHttpOnly(bool $httpOnly = true): static + { + $cookie = clone $this; + $cookie->httpOnly = $httpOnly; + + return $cookie; + } + + /** + * Creates a cookie copy that uses no url encoding. + */ + public function withRaw(bool $raw = true): static + { + if ($raw && false !== strpbrk($this->name, self::RESERVED_CHARS_LIST)) { + throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $this->name)); + } + + $cookie = clone $this; + $cookie->raw = $raw; + + return $cookie; + } + + /** + * Creates a cookie copy with SameSite attribute. + */ + public function withSameSite(?string $sameSite): static + { if ('' === $sameSite) { $sameSite = null; } elseif (null !== $sameSite) { @@ -129,20 +224,21 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.'); } - $this->sameSite = $sameSite; + $cookie = clone $this; + $cookie->sameSite = $sameSite; + + return $cookie; } /** * Returns the cookie as a string. - * - * @return string The cookie */ - public function __toString() + public function __toString(): string { if ($this->isRaw()) { $str = $this->getName(); } else { - $str = str_replace(self::$reservedCharsFrom, self::$reservedCharsTo, $this->getName()); + $str = str_replace(self::RESERVED_CHARS_FROM, self::RESERVED_CHARS_TO, $this->getName()); } $str .= '='; @@ -182,50 +278,40 @@ public function __toString() /** * Gets the name of the cookie. - * - * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** * Gets the value of the cookie. - * - * @return string|null */ - public function getValue() + public function getValue(): ?string { return $this->value; } /** * Gets the domain that the cookie is available to. - * - * @return string|null */ - public function getDomain() + public function getDomain(): ?string { return $this->domain; } /** * Gets the time the cookie expires. - * - * @return int */ - public function getExpiresTime() + public function getExpiresTime(): int { return $this->expire; } /** * Gets the max-age attribute. - * - * @return int */ - public function getMaxAge() + public function getMaxAge(): int { $maxAge = $this->expire - time(); @@ -234,60 +320,48 @@ public function getMaxAge() /** * Gets the path on the server in which the cookie will be available on. - * - * @return string */ - public function getPath() + public function getPath(): string { return $this->path; } /** * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client. - * - * @return bool */ - public function isSecure() + public function isSecure(): bool { return $this->secure ?? $this->secureDefault; } /** * Checks whether the cookie will be made accessible only through the HTTP protocol. - * - * @return bool */ - public function isHttpOnly() + public function isHttpOnly(): bool { return $this->httpOnly; } /** * Whether this cookie is about to be cleared. - * - * @return bool */ - public function isCleared() + public function isCleared(): bool { return 0 !== $this->expire && $this->expire < time(); } /** * Checks if the cookie value should be sent with no url encoding. - * - * @return bool */ - public function isRaw() + public function isRaw(): bool { return $this->raw; } /** * Gets the SameSite attribute. - * - * @return string|null */ - public function getSameSite() + public function getSameSite(): ?string { return $this->sameSite; } diff --git a/lam/lib/3rdParty/composer/symfony/mime/Exception/InvalidArgumentException.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/BadRequestException.php similarity index 55% rename from lam/lib/3rdParty/composer/symfony/mime/Exception/InvalidArgumentException.php rename to lam/lib/3rdParty/composer/symfony/http-foundation/Exception/BadRequestException.php index e89ebae20..e4bb309c4 100644 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/InvalidArgumentException.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/BadRequestException.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Mime\Exception; +namespace Symfony\Component\HttpFoundation\Exception; /** - * @author Fabien Potencier + * Raised when a user sends a malformed request. */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +class BadRequestException extends \UnexpectedValueException implements RequestExceptionInterface { } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/JsonException.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/JsonException.php new file mode 100644 index 000000000..5990e760e --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/JsonException.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\HttpFoundation\Exception; + +/** + * Thrown by Request::toArray() when the content cannot be JSON-decoded. + * + * @author Tobias Nyholm + */ +final class JsonException extends \UnexpectedValueException implements RequestExceptionInterface +{ +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/SessionNotFoundException.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/SessionNotFoundException.php new file mode 100644 index 000000000..94b0cb69a --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Exception/SessionNotFoundException.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Exception; + +/** + * Raised when a session does not exist. This happens in the following cases: + * - the session is not enabled + * - attempt to read a session outside a request context (ie. cli script). + * + * @author Jérémy Derussé + */ +class SessionNotFoundException extends \LogicException implements RequestExceptionInterface +{ + public function __construct(string $message = 'There is currently no session available.', int $code = 0, \Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/ExpressionRequestMatcher.php b/lam/lib/3rdParty/composer/symfony/http-foundation/ExpressionRequestMatcher.php index 26bed7d37..9dbf2f743 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/ExpressionRequestMatcher.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/ExpressionRequestMatcher.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpFoundation; +use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; /** @@ -23,15 +24,15 @@ class ExpressionRequestMatcher extends RequestMatcher private $language; private $expression; - public function setExpression(ExpressionLanguage $language, $expression) + public function setExpression(ExpressionLanguage $language, Expression|string $expression) { $this->language = $language; $this->expression = $expression; } - public function matches(Request $request) + public function matches(Request $request): bool { - if (!$this->language) { + if (!isset($this->language)) { throw new \LogicException('Unable to match the request as the expression language is not available.'); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/File/Exception/UnexpectedTypeException.php b/lam/lib/3rdParty/composer/symfony/http-foundation/File/Exception/UnexpectedTypeException.php index 82b982b37..905bd5962 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/File/Exception/UnexpectedTypeException.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/File/Exception/UnexpectedTypeException.php @@ -13,8 +13,8 @@ class UnexpectedTypeException extends FileException { - public function __construct($value, string $expectedType) + public function __construct(mixed $value, string $expectedType) { - parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, \is_object($value) ? \get_class($value) : \gettype($value))); + parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, get_debug_type($value))); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/File/File.php b/lam/lib/3rdParty/composer/symfony/http-foundation/File/File.php index 82d964cab..e8ce4bcf8 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/File/File.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/File/File.php @@ -47,13 +47,15 @@ public function __construct(string $path, bool $checkPath = true) * This method uses the mime type as guessed by getMimeType() * to guess the file extension. * - * @return string|null The guessed extension or null if it cannot be guessed - * * @see MimeTypes * @see getMimeType() */ - public function guessExtension() + public function guessExtension(): ?string { + if (!class_exists(MimeTypes::class)) { + throw new \LogicException('You cannot guess the extension as the Mime component is not installed. Try running "composer require symfony/mime".'); + } + return MimeTypes::getDefault()->getExtensions($this->getMimeType())[0] ?? null; } @@ -64,29 +66,32 @@ public function guessExtension() * which uses finfo_file() then the "file" system binary, * depending on which of those are available. * - * @return string|null The guessed mime type (e.g. "application/pdf") - * * @see MimeTypes */ - public function getMimeType() + public function getMimeType(): ?string { + if (!class_exists(MimeTypes::class)) { + throw new \LogicException('You cannot guess the mime type as the Mime component is not installed. Try running "composer require symfony/mime".'); + } + return MimeTypes::getDefault()->guessMimeType($this->getPathname()); } /** * Moves the file to a new location. * - * @return self A File object representing the new file - * * @throws FileException if the target file could not be created */ - public function move(string $directory, string $name = null) + public function move(string $directory, string $name = null): self { $target = $this->getTargetFile($directory, $name); set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); - $renamed = rename($this->getPathname(), $target); - restore_error_handler(); + try { + $renamed = rename($this->getPathname(), $target); + } finally { + restore_error_handler(); + } if (!$renamed) { throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error))); } @@ -96,10 +101,18 @@ public function move(string $directory, string $name = null) return $target; } - /** - * @return self - */ - protected function getTargetFile(string $directory, string $name = null) + public function getContent(): string + { + $content = file_get_contents($this->getPathname()); + + if (false === $content) { + throw new FileException(sprintf('Could not get the content of the file "%s".', $this->getPathname())); + } + + return $content; + } + + protected function getTargetFile(string $directory, string $name = null): self { if (!is_dir($directory)) { if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) { @@ -116,10 +129,8 @@ protected function getTargetFile(string $directory, string $name = null) /** * Returns locale independent base name of the given path. - * - * @return string */ - protected function getName(string $name) + protected function getName(string $name): string { $originalName = str_replace('\\', '/', $name); $pos = strrpos($originalName, '/'); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/File/Stream.php b/lam/lib/3rdParty/composer/symfony/http-foundation/File/Stream.php index 69ae74c11..2c156b2e4 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/File/Stream.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/File/Stream.php @@ -18,10 +18,7 @@ */ class Stream extends File { - /** - * {@inheritdoc} - */ - public function getSize() + public function getSize(): int|false { return false; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/File/UploadedFile.php b/lam/lib/3rdParty/composer/symfony/http-foundation/File/UploadedFile.php index fa13b01e0..5bf4cfe87 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/File/UploadedFile.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/File/UploadedFile.php @@ -31,10 +31,10 @@ */ class UploadedFile extends File { - private $test = false; - private $originalName; - private $mimeType; - private $error; + private bool $test; + private string $originalName; + private string $mimeType; + private int $error; /** * Accepts the information of the uploaded file as provided by the PHP global $_FILES. @@ -64,10 +64,10 @@ public function __construct(string $path, string $originalName, string $mimeType { $this->originalName = $this->getName($originalName); $this->mimeType = $mimeType ?: 'application/octet-stream'; - $this->error = $error ?: UPLOAD_ERR_OK; + $this->error = $error ?: \UPLOAD_ERR_OK; $this->test = $test; - parent::__construct($path, UPLOAD_ERR_OK === $this->error); + parent::__construct($path, \UPLOAD_ERR_OK === $this->error); } /** @@ -75,10 +75,8 @@ public function __construct(string $path, string $originalName, string $mimeType * * It is extracted from the request from which the file has been uploaded. * Then it should not be considered as a safe value. - * - * @return string|null The original name */ - public function getClientOriginalName() + public function getClientOriginalName(): string { return $this->originalName; } @@ -88,12 +86,10 @@ public function getClientOriginalName() * * It is extracted from the original file name that was uploaded. * Then it should not be considered as a safe value. - * - * @return string The extension */ - public function getClientOriginalExtension() + public function getClientOriginalExtension(): string { - return pathinfo($this->originalName, PATHINFO_EXTENSION); + return pathinfo($this->originalName, \PATHINFO_EXTENSION); } /** @@ -105,11 +101,9 @@ public function getClientOriginalExtension() * For a trusted mime type, use getMimeType() instead (which guesses the mime * type based on the file content). * - * @return string|null The mime type - * * @see getMimeType() */ - public function getClientMimeType() + public function getClientMimeType(): string { return $this->mimeType; } @@ -126,13 +120,15 @@ public function getClientMimeType() * For a trusted extension, use guessExtension() instead (which guesses * the extension based on the guessed mime type for the file). * - * @return string|null The guessed extension or null if it cannot be guessed - * * @see guessExtension() * @see getClientMimeType() */ - public function guessClientExtension() + public function guessClientExtension(): ?string { + if (!class_exists(MimeTypes::class)) { + throw new \LogicException('You cannot guess the extension as the Mime component is not installed. Try running "composer require symfony/mime".'); + } + return MimeTypes::getDefault()->getExtensions($this->getClientMimeType())[0] ?? null; } @@ -141,22 +137,18 @@ public function guessClientExtension() * * If the upload was successful, the constant UPLOAD_ERR_OK is returned. * Otherwise one of the other UPLOAD_ERR_XXX constants is returned. - * - * @return int The upload error */ - public function getError() + public function getError(): int { return $this->error; } /** - * Returns whether the file was uploaded successfully. - * - * @return bool True if the file has been uploaded with HTTP and no error occurred + * Returns whether the file has been uploaded with HTTP and no error occurred. */ - public function isValid() + public function isValid(): bool { - $isOk = UPLOAD_ERR_OK === $this->error; + $isOk = \UPLOAD_ERR_OK === $this->error; return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname()); } @@ -164,11 +156,9 @@ public function isValid() /** * Moves the file to a new location. * - * @return File A File object representing the new file - * * @throws FileException if, for any reason, the file could not have been moved */ - public function move(string $directory, string $name = null) + public function move(string $directory, string $name = null): File { if ($this->isValid()) { if ($this->test) { @@ -178,8 +168,11 @@ public function move(string $directory, string $name = null) $target = $this->getTargetFile($directory, $name); set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); - $moved = move_uploaded_file($this->getPathname(), $target); - restore_error_handler(); + try { + $moved = move_uploaded_file($this->getPathname(), $target); + } finally { + restore_error_handler(); + } if (!$moved) { throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error))); } @@ -190,19 +183,19 @@ public function move(string $directory, string $name = null) } switch ($this->error) { - case UPLOAD_ERR_INI_SIZE: + case \UPLOAD_ERR_INI_SIZE: throw new IniSizeFileException($this->getErrorMessage()); - case UPLOAD_ERR_FORM_SIZE: + case \UPLOAD_ERR_FORM_SIZE: throw new FormSizeFileException($this->getErrorMessage()); - case UPLOAD_ERR_PARTIAL: + case \UPLOAD_ERR_PARTIAL: throw new PartialFileException($this->getErrorMessage()); - case UPLOAD_ERR_NO_FILE: + case \UPLOAD_ERR_NO_FILE: throw new NoFileException($this->getErrorMessage()); - case UPLOAD_ERR_CANT_WRITE: + case \UPLOAD_ERR_CANT_WRITE: throw new CannotWriteFileException($this->getErrorMessage()); - case UPLOAD_ERR_NO_TMP_DIR: + case \UPLOAD_ERR_NO_TMP_DIR: throw new NoTmpDirFileException($this->getErrorMessage()); - case UPLOAD_ERR_EXTENSION: + case \UPLOAD_ERR_EXTENSION: throw new ExtensionFileException($this->getErrorMessage()); } @@ -212,20 +205,17 @@ public function move(string $directory, string $name = null) /** * Returns the maximum size of an uploaded file as configured in php.ini. * - * @return int The maximum size of an uploaded file in bytes + * @return int|float The maximum size of an uploaded file in bytes (returns float if size > PHP_INT_MAX) */ - public static function getMaxFilesize() + public static function getMaxFilesize(): int|float { - $sizePostMax = self::parseFilesize(ini_get('post_max_size')); - $sizeUploadMax = self::parseFilesize(ini_get('upload_max_filesize')); + $sizePostMax = self::parseFilesize(\ini_get('post_max_size')); + $sizeUploadMax = self::parseFilesize(\ini_get('upload_max_filesize')); - return min($sizePostMax ?: PHP_INT_MAX, $sizeUploadMax ?: PHP_INT_MAX); + return min($sizePostMax ?: \PHP_INT_MAX, $sizeUploadMax ?: \PHP_INT_MAX); } - /** - * Returns the given size from an ini value in bytes. - */ - private static function parseFilesize($size): int + private static function parseFilesize(string $size): int|float { if ('' === $size) { return 0; @@ -234,9 +224,9 @@ private static function parseFilesize($size): int $size = strtolower($size); $max = ltrim($size, '+'); - if (0 === strpos($max, '0x')) { + if (str_starts_with($max, '0x')) { $max = \intval($max, 16); - } elseif (0 === strpos($max, '0')) { + } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; @@ -244,11 +234,11 @@ private static function parseFilesize($size): int switch (substr($size, -1)) { case 't': $max *= 1024; - // no break + // no break case 'g': $max *= 1024; - // no break + // no break case 'm': $max *= 1024; - // no break + // no break case 'k': $max *= 1024; } @@ -257,24 +247,22 @@ private static function parseFilesize($size): int /** * Returns an informative upload error message. - * - * @return string The error message regarding the specified error code */ - public function getErrorMessage() + public function getErrorMessage(): string { static $errors = [ - UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).', - UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.', - UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.', - UPLOAD_ERR_NO_FILE => 'No file was uploaded.', - UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.', - UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.', - UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.', + \UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).', + \UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.', + \UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.', + \UPLOAD_ERR_NO_FILE => 'No file was uploaded.', + \UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.', + \UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.', + \UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.', ]; $errorCode = $this->error; - $maxFilesize = UPLOAD_ERR_INI_SIZE === $errorCode ? self::getMaxFilesize() / 1024 : 0; - $message = isset($errors[$errorCode]) ? $errors[$errorCode] : 'The file "%s" was not uploaded due to an unknown error.'; + $maxFilesize = \UPLOAD_ERR_INI_SIZE === $errorCode ? self::getMaxFilesize() / 1024 : 0; + $message = $errors[$errorCode] ?? 'The file "%s" was not uploaded due to an unknown error.'; return sprintf($message, $this->getClientOriginalName(), $maxFilesize); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/FileBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/FileBag.php index 5edd372b6..fdf514a12 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/FileBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/FileBag.php @@ -21,7 +21,7 @@ */ class FileBag extends ParameterBag { - private static $fileKeys = ['error', 'name', 'size', 'tmp_name', 'type']; + private const FILE_KEYS = ['error', 'name', 'size', 'tmp_name', 'type']; /** * @param array|UploadedFile[] $parameters An array of HTTP files @@ -43,7 +43,7 @@ public function replace(array $files = []) /** * {@inheritdoc} */ - public function set(string $key, $value) + public function set(string $key, mixed $value) { if (!\is_array($value) && !$value instanceof UploadedFile) { throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.'); @@ -65,32 +65,28 @@ public function add(array $files = []) /** * Converts uploaded files to UploadedFile instances. * - * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information - * - * @return UploadedFile[]|UploadedFile|null A (multi-dimensional) array of UploadedFile instances + * @return UploadedFile[]|UploadedFile|null */ - protected function convertFileInformation($file) + protected function convertFileInformation(array|UploadedFile $file): array|UploadedFile|null { if ($file instanceof UploadedFile) { return $file; } - if (\is_array($file)) { - $file = $this->fixPhpFilesArray($file); - $keys = array_keys($file); - sort($keys); - - if ($keys == self::$fileKeys) { - if (UPLOAD_ERR_NO_FILE == $file['error']) { - $file = null; - } else { - $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false); - } + $file = $this->fixPhpFilesArray($file); + $keys = array_keys($file); + sort($keys); + + if (self::FILE_KEYS == $keys) { + if (\UPLOAD_ERR_NO_FILE == $file['error']) { + $file = null; } else { - $file = array_map([$this, 'convertFileInformation'], $file); - if (array_keys($keys) === $keys) { - $file = array_filter($file); - } + $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false); + } + } else { + $file = array_map(function ($v) { return $v instanceof UploadedFile || \is_array($v) ? $this->convertFileInformation($v) : $v; }, $file); + if (array_keys($keys) === $keys) { + $file = array_filter($file); } } @@ -108,22 +104,20 @@ protected function convertFileInformation($file) * * It's safe to pass an already converted array, in which case this method * just returns the original array unmodified. - * - * @param array $data - * - * @return array */ - protected function fixPhpFilesArray($data) + protected function fixPhpFilesArray(array $data): array { + // Remove extra key added by PHP 8.1. + unset($data['full_path']); $keys = array_keys($data); sort($keys); - if (self::$fileKeys != $keys || !isset($data['name']) || !\is_array($data['name'])) { + if (self::FILE_KEYS != $keys || !isset($data['name']) || !\is_array($data['name'])) { return $data; } $files = $data; - foreach (self::$fileKeys as $k) { + foreach (self::FILE_KEYS as $k) { unset($files[$k]); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderBag.php index d45d95e09..0883024b3 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderBag.php @@ -15,12 +15,17 @@ * HeaderBag is a container for HTTP headers. * * @author Fabien Potencier + * + * @implements \IteratorAggregate> */ class HeaderBag implements \IteratorAggregate, \Countable { protected const UPPER = '_ABCDEFGHIJKLMNOPQRSTUVWXYZ'; protected const LOWER = '-abcdefghijklmnopqrstuvwxyz'; + /** + * @var array> + */ protected $headers = []; protected $cacheControl = []; @@ -33,10 +38,8 @@ public function __construct(array $headers = []) /** * Returns the headers as a string. - * - * @return string The headers */ - public function __toString() + public function __toString(): string { if (!$headers = $this->all()) { return ''; @@ -60,9 +63,9 @@ public function __toString() * * @param string|null $key The name of the headers to return or null to get them all * - * @return array An array of headers + * @return array>|array */ - public function all(string $key = null) + public function all(string $key = null): array { if (null !== $key) { return $this->headers[strtr($key, self::UPPER, self::LOWER)] ?? []; @@ -74,9 +77,9 @@ public function all(string $key = null) /** * Returns the parameter keys. * - * @return array An array of parameter keys + * @return string[] */ - public function keys() + public function keys(): array { return array_keys($this->all()); } @@ -101,11 +104,9 @@ public function add(array $headers) } /** - * Returns a header value by name. - * - * @return string|null The first header value or default value + * Returns the first header by name or the default one. */ - public function get(string $key, string $default = null) + public function get(string $key, string $default = null): ?string { $headers = $this->all($key); @@ -123,10 +124,10 @@ public function get(string $key, string $default = null) /** * Sets a header by name. * - * @param string|string[] $values The value or an array of values - * @param bool $replace Whether to replace the actual value or not (true by default) + * @param string|string[]|null $values The value or an array of values + * @param bool $replace Whether to replace the actual value or not (true by default) */ - public function set(string $key, $values, bool $replace = true) + public function set(string $key, string|array|null $values, bool $replace = true) { $key = strtr($key, self::UPPER, self::LOWER); @@ -153,20 +154,16 @@ public function set(string $key, $values, bool $replace = true) /** * Returns true if the HTTP header is defined. - * - * @return bool true if the parameter exists, false otherwise */ - public function has(string $key) + public function has(string $key): bool { return \array_key_exists(strtr($key, self::UPPER, self::LOWER), $this->all()); } /** * Returns true if the given HTTP header contains the given value. - * - * @return bool true if the value is contained in the header, false otherwise */ - public function contains(string $key, string $value) + public function contains(string $key, string $value): bool { return \in_array($value, $this->all($key)); } @@ -188,17 +185,15 @@ public function remove(string $key) /** * Returns the HTTP header value converted to a date. * - * @return \DateTimeInterface|null The parsed DateTime or the default value if the header does not exist - * * @throws \RuntimeException When the HTTP header is not parseable */ - public function getDate(string $key, \DateTime $default = null) + public function getDate(string $key, \DateTime $default = null): ?\DateTimeInterface { if (null === $value = $this->get($key)) { return $default; } - if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { + if (false === $date = \DateTime::createFromFormat(\DATE_RFC2822, $value)) { throw new \RuntimeException(sprintf('The "%s" HTTP header is not parseable (%s).', $key, $value)); } @@ -207,10 +202,8 @@ public function getDate(string $key, \DateTime $default = null) /** * Adds a custom Cache-Control directive. - * - * @param mixed $value The Cache-Control directive value */ - public function addCacheControlDirective(string $key, $value = true) + public function addCacheControlDirective(string $key, bool|string $value = true) { $this->cacheControl[$key] = $value; @@ -219,22 +212,18 @@ public function addCacheControlDirective(string $key, $value = true) /** * Returns true if the Cache-Control directive is defined. - * - * @return bool true if the directive exists, false otherwise */ - public function hasCacheControlDirective(string $key) + public function hasCacheControlDirective(string $key): bool { return \array_key_exists($key, $this->cacheControl); } /** * Returns a Cache-Control directive value by name. - * - * @return mixed|null The directive value if defined, null otherwise */ - public function getCacheControlDirective(string $key) + public function getCacheControlDirective(string $key): bool|string|null { - return \array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; + return $this->cacheControl[$key] ?? null; } /** @@ -250,19 +239,17 @@ public function removeCacheControlDirective(string $key) /** * Returns an iterator for headers. * - * @return \ArrayIterator An \ArrayIterator instance + * @return \ArrayIterator> */ - public function getIterator() + public function getIterator(): \ArrayIterator { return new \ArrayIterator($this->headers); } /** * Returns the number of headers. - * - * @return int The number of headers */ - public function count() + public function count(): int { return \count($this->headers); } @@ -276,10 +263,8 @@ protected function getCacheControlHeader() /** * Parses a Cache-Control HTTP header. - * - * @return array An array representing the attribute values */ - protected function parseCacheControl(string $header) + protected function parseCacheControl(string $header): array { $parts = HeaderUtils::split($header, ',='); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderUtils.php b/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderUtils.php index 5866e3b2b..1d56be080 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderUtils.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/HeaderUtils.php @@ -62,7 +62,7 @@ public static function split(string $header, string $separators): array \s* (?['.$quotedSeparators.']) \s* - /x', trim($header), $matches, PREG_SET_ORDER); + /x', trim($header), $matches, \PREG_SET_ORDER); return self::groupParts($matches, $separators); } @@ -146,7 +146,7 @@ public static function unquote(string $s): string } /** - * Generates a HTTP Content-Disposition field-value. + * Generates an HTTP Content-Disposition field-value. * * @param string $disposition One of "inline" or "attachment" * @param string $filename A unicode string @@ -154,8 +154,6 @@ public static function unquote(string $s): string * is semantically equivalent to $filename. If the filename is already ASCII, * it can be omitted, or just copied from $filename * - * @return string A string suitable for use as a Content-Disposition field-value - * * @throws \InvalidArgumentException * * @see RFC 6266 @@ -176,12 +174,12 @@ public static function makeDisposition(string $disposition, string $filename, st } // percent characters aren't safe in fallback. - if (false !== strpos($filenameFallback, '%')) { + if (str_contains($filenameFallback, '%')) { throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); } // path separators aren't allowed in either. - if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) { + if (str_contains($filename, '/') || str_contains($filename, '\\') || str_contains($filenameFallback, '/') || str_contains($filenameFallback, '\\')) { throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); } @@ -193,17 +191,81 @@ public static function makeDisposition(string $disposition, string $filename, st return $disposition.'; '.self::toString($params, ';'); } - private static function groupParts(array $matches, string $separators): array + /** + * Like parse_str(), but preserves dots in variable names. + */ + public static function parseQuery(string $query, bool $ignoreBrackets = false, string $separator = '&'): array + { + $q = []; + + foreach (explode($separator, $query) as $v) { + if (false !== $i = strpos($v, "\0")) { + $v = substr($v, 0, $i); + } + + if (false === $i = strpos($v, '=')) { + $k = urldecode($v); + $v = ''; + } else { + $k = urldecode(substr($v, 0, $i)); + $v = substr($v, $i); + } + + if (false !== $i = strpos($k, "\0")) { + $k = substr($k, 0, $i); + } + + $k = ltrim($k, ' '); + + if ($ignoreBrackets) { + $q[$k][] = urldecode(substr($v, 1)); + + continue; + } + + if (false === $i = strpos($k, '[')) { + $q[] = bin2hex($k).$v; + } else { + $q[] = bin2hex(substr($k, 0, $i)).rawurlencode(substr($k, $i)).$v; + } + } + + if ($ignoreBrackets) { + return $q; + } + + parse_str(implode('&', $q), $q); + + $query = []; + + foreach ($q as $k => $v) { + if (false !== $i = strpos($k, '_')) { + $query[substr_replace($k, hex2bin(substr($k, 0, $i)).'[', 0, 1 + $i)] = $v; + } else { + $query[hex2bin($k)] = $v; + } + } + + return $query; + } + + private static function groupParts(array $matches, string $separators, bool $first = true): array { $separator = $separators[0]; $partSeparators = substr($separators, 1); $i = 0; $partMatches = []; + $previousMatchWasSeparator = false; foreach ($matches as $match) { - if (isset($match['separator']) && $match['separator'] === $separator) { + if (!$first && $previousMatchWasSeparator && isset($match['separator']) && $match['separator'] === $separator) { + $previousMatchWasSeparator = true; + $partMatches[$i][] = $match; + } elseif (isset($match['separator']) && $match['separator'] === $separator) { + $previousMatchWasSeparator = true; ++$i; } else { + $previousMatchWasSeparator = false; $partMatches[$i][] = $match; } } @@ -211,12 +273,19 @@ private static function groupParts(array $matches, string $separators): array $parts = []; if ($partSeparators) { foreach ($partMatches as $matches) { - $parts[] = self::groupParts($matches, $partSeparators); + $parts[] = self::groupParts($matches, $partSeparators, false); } } else { foreach ($partMatches as $matches) { $parts[] = self::unquote($matches[0][0]); } + + if (!$first && 2 < \count($parts)) { + $parts = [ + $parts[0], + implode($separator, \array_slice($parts, 1)), + ]; + } } return $parts; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/InputBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/InputBag.php new file mode 100644 index 000000000..fd833467f --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/InputBag.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\HttpFoundation; + +use Symfony\Component\HttpFoundation\Exception\BadRequestException; + +/** + * InputBag is a container for user input values such as $_GET, $_POST, $_REQUEST, and $_COOKIE. + * + * @author Saif Eddin Gmati + */ +final class InputBag extends ParameterBag +{ + /** + * Returns a scalar input value by name. + * + * @param string|int|float|bool|null $default The default value if the input key does not exist + */ + public function get(string $key, mixed $default = null): string|int|float|bool|null + { + if (null !== $default && !\is_scalar($default) && !$default instanceof \Stringable) { + throw new \InvalidArgumentException(sprintf('Expected a scalar value as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($default))); + } + + $value = parent::get($key, $this); + + if (null !== $value && $this !== $value && !\is_scalar($value) && !$value instanceof \Stringable) { + throw new BadRequestException(sprintf('Input value "%s" contains a non-scalar value.', $key)); + } + + return $this === $value ? $default : $value; + } + + /** + * Replaces the current input values by a new set. + */ + public function replace(array $inputs = []) + { + $this->parameters = []; + $this->add($inputs); + } + + /** + * Adds input values. + */ + public function add(array $inputs = []) + { + foreach ($inputs as $input => $value) { + $this->set($input, $value); + } + } + + /** + * Sets an input by name. + * + * @param string|int|float|bool|array|null $value + */ + public function set(string $key, mixed $value) + { + if (null !== $value && !\is_scalar($value) && !\is_array($value) && !$value instanceof \Stringable) { + throw new \InvalidArgumentException(sprintf('Expected a scalar, or an array as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($value))); + } + + $this->parameters[$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function filter(string $key, mixed $default = null, int $filter = \FILTER_DEFAULT, mixed $options = []): mixed + { + $value = $this->has($key) ? $this->all()[$key] : $default; + + // Always turn $options into an array - this allows filter_var option shortcuts. + if (!\is_array($options) && $options) { + $options = ['flags' => $options]; + } + + if (\is_array($value) && !(($options['flags'] ?? 0) & (\FILTER_REQUIRE_ARRAY | \FILTER_FORCE_ARRAY))) { + throw new BadRequestException(sprintf('Input value "%s" contains an array, but "FILTER_REQUIRE_ARRAY" or "FILTER_FORCE_ARRAY" flags were not set.', $key)); + } + + if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) { + throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null))); + } + + return filter_var($value, $filter, $options); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/IpUtils.php b/lam/lib/3rdParty/composer/symfony/http-foundation/IpUtils.php index 80c5a950c..51c698e4e 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/IpUtils.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/IpUtils.php @@ -18,7 +18,7 @@ */ class IpUtils { - private static $checkedIps = []; + private static array $checkedIps = []; /** * This class should not be instantiated. @@ -31,10 +31,8 @@ private function __construct() * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets. * * @param string|array $ips List of IPs or subnets (can be a string if only a single one) - * - * @return bool Whether the IP is valid */ - public static function checkIp(?string $requestIp, $ips) + public static function checkIp(string $requestIp, string|array $ips): bool { if (!\is_array($ips)) { $ips = [$ips]; @@ -59,22 +57,22 @@ public static function checkIp(?string $requestIp, $ips) * * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet */ - public static function checkIp4(?string $requestIp, string $ip) + public static function checkIp4(string $requestIp, string $ip): bool { $cacheKey = $requestIp.'-'.$ip; if (isset(self::$checkedIps[$cacheKey])) { return self::$checkedIps[$cacheKey]; } - if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { return self::$checkedIps[$cacheKey] = false; } - if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); + if (str_contains($ip, '/')) { + [$address, $netmask] = explode('/', $ip, 2); if ('0' === $netmask) { - return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + return self::$checkedIps[$cacheKey] = false !== filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4); } if ($netmask < 0 || $netmask > 32) { @@ -102,11 +100,9 @@ public static function checkIp4(?string $requestIp, string $ip) * * @param string $ip IPv6 address or subnet in CIDR notation * - * @return bool Whether the IP is valid - * * @throws \RuntimeException When IPV6 support is not enabled */ - public static function checkIp6(?string $requestIp, string $ip) + public static function checkIp6(string $requestIp, string $ip): bool { $cacheKey = $requestIp.'-'.$ip; if (isset(self::$checkedIps[$cacheKey])) { @@ -117,8 +113,17 @@ public static function checkIp6(?string $requestIp, string $ip) throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); } - if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); + // Check to see if we were given a IP4 $requestIp or $ip by mistake + if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + return self::$checkedIps[$cacheKey] = false; + } + + if (str_contains($ip, '/')) { + [$address, $netmask] = explode('/', $ip, 2); + + if (!filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + return self::$checkedIps[$cacheKey] = false; + } if ('0' === $netmask) { return (bool) unpack('n*', @inet_pton($address)); @@ -128,6 +133,10 @@ public static function checkIp6(?string $requestIp, string $ip) return self::$checkedIps[$cacheKey] = false; } } else { + if (!filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + return self::$checkedIps[$cacheKey] = false; + } + $address = $ip; $netmask = 128; } @@ -142,7 +151,7 @@ public static function checkIp6(?string $requestIp, string $ip) for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) { $left = $netmask - 16 * ($i - 1); $left = ($left <= 16) ? $left : 16; - $mask = ~(0xffff >> $left) & 0xffff; + $mask = ~(0xFFFF >> $left) & 0xFFFF; if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) { return self::$checkedIps[$cacheKey] = false; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/JsonResponse.php b/lam/lib/3rdParty/composer/symfony/http-foundation/JsonResponse.php index 8489bc0b1..4d55cd5c4 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/JsonResponse.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/JsonResponse.php @@ -29,20 +29,21 @@ class JsonResponse extends Response // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML. // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT - const DEFAULT_ENCODING_OPTIONS = 15; + public const DEFAULT_ENCODING_OPTIONS = 15; protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS; /** - * @param mixed $data The response data - * @param int $status The response status code - * @param array $headers An array of response headers - * @param bool $json If the data is already a JSON string + * @param bool $json If the data is already a JSON string */ - public function __construct($data = null, int $status = 200, array $headers = [], bool $json = false) + public function __construct(mixed $data = null, int $status = 200, array $headers = [], bool $json = false) { parent::__construct('', $status, $headers); + if ($json && !\is_string($data) && !is_numeric($data) && !\is_callable([$data, '__toString'])) { + throw new \TypeError(sprintf('"%s": If $json is set to true, argument $data must be a string or object implementing __toString(), "%s" given.', __METHOD__, get_debug_type($data))); + } + if (null === $data) { $data = new \ArrayObject(); } @@ -50,25 +51,6 @@ public function __construct($data = null, int $status = 200, array $headers = [] $json ? $this->setJson($data) : $this->setData($data); } - /** - * Factory method for chainability. - * - * Example: - * - * return JsonResponse::create(['key' => 'value']) - * ->setSharedMaxAge(300); - * - * @param mixed $data The JSON response data - * @param int $status The response status code - * @param array $headers An array of response headers - * - * @return static - */ - public static function create($data = null, int $status = 200, array $headers = []) - { - return new static($data, $status, $headers); - } - /** * Factory method for chainability. * @@ -77,13 +59,11 @@ public static function create($data = null, int $status = 200, array $headers = * return JsonResponse::fromJsonString('{"key": "value"}') * ->setSharedMaxAge(300); * - * @param string|null $data The JSON response string - * @param int $status The response status code - * @param array $headers An array of response headers - * - * @return static + * @param string $data The JSON response string + * @param int $status The response status code + * @param array $headers An array of response headers */ - public static function fromJsonString(string $data = null, int $status = 200, array $headers = []) + public static function fromJsonString(string $data, int $status = 200, array $headers = []): static { return new static($data, $status, $headers, true); } @@ -97,7 +77,7 @@ public static function fromJsonString(string $data = null, int $status = 200, ar * * @throws \InvalidArgumentException When the callback name is not valid */ - public function setCallback(string $callback = null) + public function setCallback(string $callback = null): static { if (null !== $callback) { // partially taken from https://geekality.net/2011/08/03/valid-javascript-identifier/ @@ -127,10 +107,8 @@ public function setCallback(string $callback = null) * Sets a raw string containing a JSON document to be sent. * * @return $this - * - * @throws \InvalidArgumentException */ - public function setJson(string $json) + public function setJson(string $json): static { $this->data = $json; @@ -140,28 +118,26 @@ public function setJson(string $json) /** * Sets the data to be sent as JSON. * - * @param mixed $data - * * @return $this * * @throws \InvalidArgumentException */ - public function setData($data = []) + public function setData(mixed $data = []): static { try { $data = json_encode($data, $this->encodingOptions); } catch (\Exception $e) { - if ('Exception' === \get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + if ('Exception' === \get_class($e) && str_starts_with($e->getMessage(), 'Failed calling ')) { throw $e->getPrevious() ?: $e; } throw $e; } - if (\PHP_VERSION_ID >= 70300 && (JSON_THROW_ON_ERROR & $this->encodingOptions)) { + if (\JSON_THROW_ON_ERROR & $this->encodingOptions) { return $this->setJson($data); } - if (JSON_ERROR_NONE !== json_last_error()) { + if (\JSON_ERROR_NONE !== json_last_error()) { throw new \InvalidArgumentException(json_last_error_msg()); } @@ -170,10 +146,8 @@ public function setData($data = []) /** * Returns options used while encoding data to JSON. - * - * @return int */ - public function getEncodingOptions() + public function getEncodingOptions(): int { return $this->encodingOptions; } @@ -183,7 +157,7 @@ public function getEncodingOptions() * * @return $this */ - public function setEncodingOptions(int $encodingOptions) + public function setEncodingOptions(int $encodingOptions): static { $this->encodingOptions = $encodingOptions; @@ -195,7 +169,7 @@ public function setEncodingOptions(int $encodingOptions) * * @return $this */ - protected function update() + protected function update(): static { if (null !== $this->callback) { // Not using application/javascript for compatibility reasons with older browsers. diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/LICENSE b/lam/lib/3rdParty/composer/symfony/http-foundation/LICENSE index 9e936ec04..008370457 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/LICENSE +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2020 Fabien Potencier +Copyright (c) 2004-2023 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/lam/lib/3rdParty/composer/symfony/http-foundation/ParameterBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/ParameterBag.php index 212149c7b..6044dac9f 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/ParameterBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/ParameterBag.php @@ -11,10 +11,14 @@ namespace Symfony\Component\HttpFoundation; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; + /** * ParameterBag is a container for key/value pairs. * * @author Fabien Potencier + * + * @implements \IteratorAggregate */ class ParameterBag implements \IteratorAggregate, \Countable { @@ -31,19 +35,25 @@ public function __construct(array $parameters = []) /** * Returns the parameters. * - * @return array An array of parameters + * @param string|null $key The name of the parameter to return or null to get them all */ - public function all() + public function all(string $key = null): array { - return $this->parameters; + if (null === $key) { + return $this->parameters; + } + + if (!\is_array($value = $this->parameters[$key] ?? [])) { + throw new BadRequestException(sprintf('Unexpected value for parameter "%s": expecting "array", got "%s".', $key, get_debug_type($value))); + } + + return $value; } /** * Returns the parameter keys. - * - * @return array An array of parameter keys */ - public function keys() + public function keys(): array { return array_keys($this->parameters); } @@ -64,34 +74,20 @@ public function add(array $parameters = []) $this->parameters = array_replace($this->parameters, $parameters); } - /** - * Returns a parameter by name. - * - * @param mixed $default The default value if the parameter key does not exist - * - * @return mixed - */ - public function get(string $key, $default = null) + public function get(string $key, mixed $default = null): mixed { return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default; } - /** - * Sets a parameter by name. - * - * @param mixed $value The value - */ - public function set(string $key, $value) + public function set(string $key, mixed $value) { $this->parameters[$key] = $value; } /** * Returns true if the parameter is defined. - * - * @return bool true if the parameter exists, false otherwise */ - public function has(string $key) + public function has(string $key): bool { return \array_key_exists($key, $this->parameters); } @@ -106,67 +102,53 @@ public function remove(string $key) /** * Returns the alphabetic characters of the parameter value. - * - * @return string The filtered value */ - public function getAlpha(string $key, string $default = '') + public function getAlpha(string $key, string $default = ''): string { return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default)); } /** * Returns the alphabetic characters and digits of the parameter value. - * - * @return string The filtered value */ - public function getAlnum(string $key, string $default = '') + public function getAlnum(string $key, string $default = ''): string { return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default)); } /** * Returns the digits of the parameter value. - * - * @return string The filtered value */ - public function getDigits(string $key, string $default = '') + public function getDigits(string $key, string $default = ''): string { // we need to remove - and + because they're allowed in the filter - return str_replace(['-', '+'], '', $this->filter($key, $default, FILTER_SANITIZE_NUMBER_INT)); + return str_replace(['-', '+'], '', $this->filter($key, $default, \FILTER_SANITIZE_NUMBER_INT)); } /** * Returns the parameter value converted to integer. - * - * @return int The filtered value */ - public function getInt(string $key, int $default = 0) + public function getInt(string $key, int $default = 0): int { return (int) $this->get($key, $default); } /** * Returns the parameter value converted to boolean. - * - * @return bool The filtered value */ - public function getBoolean(string $key, bool $default = false) + public function getBoolean(string $key, bool $default = false): bool { - return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN); + return $this->filter($key, $default, \FILTER_VALIDATE_BOOLEAN); } /** * Filter key. * - * @param mixed $default Default = null - * @param int $filter FILTER_* constant - * @param mixed $options Filter options + * @param int $filter FILTER_* constant * * @see https://php.net/filter-var - * - * @return mixed */ - public function filter(string $key, $default = null, int $filter = FILTER_DEFAULT, $options = []) + public function filter(string $key, mixed $default = null, int $filter = \FILTER_DEFAULT, mixed $options = []): mixed { $value = $this->get($key, $default); @@ -177,7 +159,11 @@ public function filter(string $key, $default = null, int $filter = FILTER_DEFAUL // Add a convenience check for arrays. if (\is_array($value) && !isset($options['flags'])) { - $options['flags'] = FILTER_REQUIRE_ARRAY; + $options['flags'] = \FILTER_REQUIRE_ARRAY; + } + + if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) { + throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null))); } return filter_var($value, $filter, $options); @@ -186,19 +172,17 @@ public function filter(string $key, $default = null, int $filter = FILTER_DEFAUL /** * Returns an iterator for parameters. * - * @return \ArrayIterator An \ArrayIterator instance + * @return \ArrayIterator */ - public function getIterator() + public function getIterator(): \ArrayIterator { return new \ArrayIterator($this->parameters); } /** * Returns the number of parameters. - * - * @return int The number of parameters */ - public function count() + public function count(): int { return \count($this->parameters); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/README.md b/lam/lib/3rdParty/composer/symfony/http-foundation/README.md index ac98f9b80..424f2c4f0 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/README.md +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/README.md @@ -4,11 +4,25 @@ HttpFoundation Component The HttpFoundation component defines an object-oriented layer for the HTTP specification. +Sponsor +------- + +The HttpFoundation component for Symfony 5.4/6.0 is [backed][1] by [Laravel][2]. + +Laravel is a PHP web development framework that is passionate about maximum developer +happiness. Laravel is built using a variety of bespoke and Symfony based components. + +Help Symfony by [sponsoring][3] its development! + Resources --------- - * [Documentation](https://symfony.com/doc/current/components/http_foundation.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) + * [Documentation](https://symfony.com/doc/current/components/http_foundation.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) + +[1]: https://symfony.com/backers +[2]: https://laravel.com/ +[3]: https://symfony.com/sponsor diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php new file mode 100644 index 000000000..a6dd993b7 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.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\HttpFoundation\RateLimiter; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\RateLimiter\LimiterInterface; +use Symfony\Component\RateLimiter\Policy\NoLimiter; +use Symfony\Component\RateLimiter\RateLimit; + +/** + * An implementation of RequestRateLimiterInterface that + * fits most use-cases. + * + * @author Wouter de Jong + */ +abstract class AbstractRequestRateLimiter implements RequestRateLimiterInterface +{ + public function consume(Request $request): RateLimit + { + $limiters = $this->getLimiters($request); + if (0 === \count($limiters)) { + $limiters = [new NoLimiter()]; + } + + $minimalRateLimit = null; + foreach ($limiters as $limiter) { + $rateLimit = $limiter->consume(1); + + $minimalRateLimit = $minimalRateLimit ? self::getMinimalRateLimit($minimalRateLimit, $rateLimit) : $rateLimit; + } + + return $minimalRateLimit; + } + + public function reset(Request $request): void + { + foreach ($this->getLimiters($request) as $limiter) { + $limiter->reset(); + } + } + + /** + * @return LimiterInterface[] a set of limiters using keys extracted from the request + */ + abstract protected function getLimiters(Request $request): array; + + private static function getMinimalRateLimit(RateLimit $first, RateLimit $second): RateLimit + { + if ($first->isAccepted() !== $second->isAccepted()) { + return $first->isAccepted() ? $second : $first; + } + + $firstRemainingTokens = $first->getRemainingTokens(); + $secondRemainingTokens = $second->getRemainingTokens(); + + if ($firstRemainingTokens === $secondRemainingTokens) { + return $first->getRetryAfter() < $second->getRetryAfter() ? $second : $first; + } + + return $firstRemainingTokens > $secondRemainingTokens ? $second : $first; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/RequestRateLimiterInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/RequestRateLimiterInterface.php new file mode 100644 index 000000000..4c87a40a8 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RateLimiter/RequestRateLimiterInterface.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\HttpFoundation\RateLimiter; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\RateLimiter\RateLimit; + +/** + * A special type of limiter that deals with requests. + * + * This allows to limit on different types of information + * from the requests. + * + * @author Wouter de Jong + */ +interface RequestRateLimiterInterface +{ + public function consume(Request $request): RateLimit; + + public function reset(Request $request): void; +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RedirectResponse.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RedirectResponse.php index c6d7590ef..f70bd286d 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/RedirectResponse.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RedirectResponse.php @@ -42,29 +42,15 @@ public function __construct(string $url, int $status = 302, array $headers = []) throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status)); } - if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, CASE_LOWER))) { + if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, \CASE_LOWER))) { $this->headers->remove('cache-control'); } } - /** - * Factory method for chainability. - * - * @param string $url The URL to redirect to - * - * @return static - */ - public static function create($url = '', int $status = 302, array $headers = []) - { - return new static($url, $status, $headers); - } - /** * Returns the target URL. - * - * @return string target URL */ - public function getTargetUrl() + public function getTargetUrl(): string { return $this->targetUrl; } @@ -76,7 +62,7 @@ public function getTargetUrl() * * @throws \InvalidArgumentException */ - public function setTargetUrl(string $url) + public function setTargetUrl(string $url): static { if ('' === $url) { throw new \InvalidArgumentException('Cannot redirect to an empty URL.'); @@ -96,7 +82,7 @@ public function setTargetUrl(string $url) Redirecting to %1$s. -', htmlspecialchars($url, ENT_QUOTES, 'UTF-8'))); +', htmlspecialchars($url, \ENT_QUOTES, 'UTF-8'))); $this->headers->set('Location', $url); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Request.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Request.php index 1abb0af6f..a20e9af15 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Request.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Request.php @@ -12,6 +12,8 @@ namespace Symfony\Component\HttpFoundation; use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException; +use Symfony\Component\HttpFoundation\Exception\JsonException; +use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; use Symfony\Component\HttpFoundation\Session\SessionInterface; @@ -20,6 +22,7 @@ class_exists(AcceptHeader::class); class_exists(FileBag::class); class_exists(HeaderBag::class); class_exists(HeaderUtils::class); +class_exists(InputBag::class); class_exists(ParameterBag::class); class_exists(ServerBag::class); @@ -38,24 +41,26 @@ class_exists(ServerBag::class); */ class Request { - const HEADER_FORWARDED = 0b00001; // When using RFC 7239 - const HEADER_X_FORWARDED_FOR = 0b00010; - const HEADER_X_FORWARDED_HOST = 0b00100; - const HEADER_X_FORWARDED_PROTO = 0b01000; - const HEADER_X_FORWARDED_PORT = 0b10000; - const HEADER_X_FORWARDED_ALL = 0b11110; // All "X-Forwarded-*" headers - const HEADER_X_FORWARDED_AWS_ELB = 0b11010; // AWS ELB doesn't send X-Forwarded-Host - - const METHOD_HEAD = 'HEAD'; - const METHOD_GET = 'GET'; - const METHOD_POST = 'POST'; - const METHOD_PUT = 'PUT'; - const METHOD_PATCH = 'PATCH'; - const METHOD_DELETE = 'DELETE'; - const METHOD_PURGE = 'PURGE'; - const METHOD_OPTIONS = 'OPTIONS'; - const METHOD_TRACE = 'TRACE'; - const METHOD_CONNECT = 'CONNECT'; + public const HEADER_FORWARDED = 0b000001; // When using RFC 7239 + public const HEADER_X_FORWARDED_FOR = 0b000010; + public const HEADER_X_FORWARDED_HOST = 0b000100; + public const HEADER_X_FORWARDED_PROTO = 0b001000; + public const HEADER_X_FORWARDED_PORT = 0b010000; + public const HEADER_X_FORWARDED_PREFIX = 0b100000; + + public const HEADER_X_FORWARDED_AWS_ELB = 0b0011010; // AWS ELB doesn't send X-Forwarded-Host + public const HEADER_X_FORWARDED_TRAEFIK = 0b0111110; // All "X-Forwarded-*" headers sent by Traefik reverse proxy + + public const METHOD_HEAD = 'HEAD'; + public const METHOD_GET = 'GET'; + public const METHOD_POST = 'POST'; + public const METHOD_PUT = 'PUT'; + public const METHOD_PATCH = 'PATCH'; + public const METHOD_DELETE = 'DELETE'; + public const METHOD_PURGE = 'PURGE'; + public const METHOD_OPTIONS = 'OPTIONS'; + public const METHOD_TRACE = 'TRACE'; + public const METHOD_CONNECT = 'CONNECT'; /** * @var string[] @@ -84,14 +89,14 @@ class Request /** * Request body parameters ($_POST). * - * @var ParameterBag + * @var InputBag */ public $request; /** * Query string parameters ($_GET). * - * @var ParameterBag + * @var InputBag */ public $query; @@ -112,7 +117,7 @@ class Request /** * Cookies ($_COOKIE). * - * @var ParameterBag + * @var InputBag */ public $cookies; @@ -179,7 +184,7 @@ class Request protected $format; /** - * @var SessionInterface + * @var SessionInterface|callable(): SessionInterface */ protected $session; @@ -200,16 +205,14 @@ class Request protected static $requestFactory; - /** - * @var string|null - */ - private $preferredFormat; - private $isHostValid = true; - private $isForwardedValid = true; + private ?string $preferredFormat = null; + private bool $isHostValid = true; + private bool $isForwardedValid = true; + private bool $isSafeContentPreferred; - private static $trustedHeaderSet = -1; + private static int $trustedHeaderSet = -1; - private static $forwardedParams = [ + private const FORWARDED_PARAMS = [ self::HEADER_X_FORWARDED_FOR => 'for', self::HEADER_X_FORWARDED_HOST => 'host', self::HEADER_X_FORWARDED_PROTO => 'proto', @@ -225,12 +228,13 @@ class Request * The other headers are non-standard, but widely used * by popular reverse proxies (like Apache mod_proxy or Amazon EC2). */ - private static $trustedHeaders = [ + private const TRUSTED_HEADERS = [ self::HEADER_FORWARDED => 'FORWARDED', self::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR', self::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST', self::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO', self::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT', + self::HEADER_X_FORWARDED_PREFIX => 'X_FORWARDED_PREFIX', ]; /** @@ -262,10 +266,10 @@ public function __construct(array $query = [], array $request = [], array $attri */ public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null) { - $this->request = new ParameterBag($request); - $this->query = new ParameterBag($query); + $this->request = new InputBag($request); + $this->query = new InputBag($query); $this->attributes = new ParameterBag($attributes); - $this->cookies = new ParameterBag($cookies); + $this->cookies = new InputBag($cookies); $this->files = new FileBag($files); $this->server = new ServerBag($server); $this->headers = new HeaderBag($this->server->getHeaders()); @@ -285,18 +289,16 @@ public function initialize(array $query = [], array $request = [], array $attrib /** * Creates a new request with values from PHP's super globals. - * - * @return static */ - public static function createFromGlobals() + public static function createFromGlobals(): static { $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER); - if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') + if (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded') && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH']) ) { parse_str($request->getContent(), $data); - $request->request = new ParameterBag($data); + $request->request = new InputBag($data); } return $request; @@ -315,10 +317,8 @@ public static function createFromGlobals() * @param array $files The request files ($_FILES) * @param array $server The server parameters ($_SERVER) * @param string|resource|null $content The raw body data - * - * @return static */ - public static function create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], $content = null) + public static function create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], $content = null): static { $server = array_replace([ 'SERVER_NAME' => 'localhost', @@ -333,6 +333,7 @@ public static function create(string $uri, string $method = 'GET', array $parame 'SCRIPT_FILENAME' => '', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'REQUEST_TIME' => time(), + 'REQUEST_TIME_FLOAT' => microtime(true), ], $server); $server['PATH_INFO'] = ''; @@ -431,23 +432,21 @@ public static function setFactory(?callable $callable) * @param array $cookies The COOKIE parameters * @param array $files The FILES parameters * @param array $server The SERVER parameters - * - * @return static */ - public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) + public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null): static { $dup = clone $this; if (null !== $query) { - $dup->query = new ParameterBag($query); + $dup->query = new InputBag($query); } if (null !== $request) { - $dup->request = new ParameterBag($request); + $dup->request = new InputBag($request); } if (null !== $attributes) { $dup->attributes = new ParameterBag($attributes); } if (null !== $cookies) { - $dup->cookies = new ParameterBag($cookies); + $dup->cookies = new InputBag($cookies); } if (null !== $files) { $dup->files = new FileBag($files); @@ -495,31 +494,18 @@ public function __clone() $this->headers = clone $this->headers; } - /** - * Returns the request as a string. - * - * @return string The request - */ - public function __toString() + public function __toString(): string { - try { - $content = $this->getContent(); - } catch (\LogicException $e) { - if (\PHP_VERSION_ID >= 70400) { - throw $e; - } - - return trigger_error($e, E_USER_ERROR); - } + $content = $this->getContent(); $cookieHeader = ''; $cookies = []; foreach ($this->cookies as $k => $v) { - $cookies[] = $k.'='.$v; + $cookies[] = \is_array($v) ? http_build_query([$k => $v], '', '; ', \PHP_QUERY_RFC3986) : "$k=$v"; } - if (!empty($cookies)) { + if ($cookies) { $cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n"; } @@ -556,7 +542,7 @@ public function overrideGlobals() $request = ['g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE]; - $requestOrder = ini_get('request_order') ?: ini_get('variables_order'); + $requestOrder = \ini_get('request_order') ?: \ini_get('variables_order'); $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp'; $_REQUEST = [[]]; @@ -575,8 +561,6 @@ public function overrideGlobals() * * @param array $proxies A list of trusted proxies, the string 'REMOTE_ADDR' will be replaced with $_SERVER['REMOTE_ADDR'] * @param int $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies - * - * @throws \InvalidArgumentException When $trustedHeaderSet is invalid */ public static function setTrustedProxies(array $proxies, int $trustedHeaderSet) { @@ -594,10 +578,8 @@ public static function setTrustedProxies(array $proxies, int $trustedHeaderSet) /** * Gets the list of trusted proxies. - * - * @return array An array of trusted proxies */ - public static function getTrustedProxies() + public static function getTrustedProxies(): array { return self::$trustedProxies; } @@ -607,7 +589,7 @@ public static function getTrustedProxies() * * @return int A bit field of Request::HEADER_* that defines which headers are trusted from your proxies */ - public static function getTrustedHeaderSet() + public static function getTrustedHeaderSet(): int { return self::$trustedHeaderSet; } @@ -630,10 +612,8 @@ public static function setTrustedHosts(array $hostPatterns) /** * Gets the list of trusted host patterns. - * - * @return array An array of trusted host patterns */ - public static function getTrustedHosts() + public static function getTrustedHosts(): array { return self::$trustedHostPatterns; } @@ -643,19 +623,17 @@ public static function getTrustedHosts() * * It builds a normalized query string, where keys/value pairs are alphabetized, * have consistent escaping and unneeded delimiters are removed. - * - * @return string A normalized query string for the Request */ - public static function normalizeQueryString(?string $qs) + public static function normalizeQueryString(?string $qs): string { if ('' === ($qs ?? '')) { return ''; } - parse_str($qs, $qs); + $qs = HeaderUtils::parseQuery($qs); ksort($qs); - return http_build_query($qs, '', '&', PHP_QUERY_RFC3986); + return http_build_query($qs, '', '&', \PHP_QUERY_RFC3986); } /** @@ -676,10 +654,8 @@ public static function enableHttpMethodParameterOverride() /** * Checks whether support for the _method request parameter is enabled. - * - * @return bool True when the _method request parameter is enabled, false otherwise */ - public static function getHttpMethodParameterOverride() + public static function getHttpMethodParameterOverride(): bool { return self::$httpMethodParameterOverride; } @@ -691,24 +667,22 @@ public static function getHttpMethodParameterOverride() * flexibility in controllers, it is better to explicitly get request parameters from the appropriate * public property instead (attributes, query, request). * - * Order of precedence: PATH (routing placeholders or custom attributes), GET, BODY - * - * @param mixed $default The default value if the parameter key does not exist + * Order of precedence: PATH (routing placeholders or custom attributes), GET, POST * - * @return mixed + * @internal use explicit input sources instead */ - public function get(string $key, $default = null) + public function get(string $key, mixed $default = null): mixed { if ($this !== $result = $this->attributes->get($key, $this)) { return $result; } - if ($this !== $result = $this->query->get($key, $this)) { - return $result; + if ($this->query->has($key)) { + return $this->query->all()[$key]; } - if ($this !== $result = $this->request->get($key, $this)) { - return $result; + if ($this->request->has($key)) { + return $this->request->all()[$key]; } return $default; @@ -716,10 +690,8 @@ public function get(string $key, $default = null) /** * Gets the Session. - * - * @return SessionInterface The session */ - public function getSession() + public function getSession(): SessionInterface { $session = $this->session; if (!$session instanceof SessionInterface && null !== $session) { @@ -727,7 +699,7 @@ public function getSession() } if (null === $session) { - throw new \BadMethodCallException('Session has not been set.'); + throw new SessionNotFoundException('Session has not been set.'); } return $session; @@ -736,10 +708,8 @@ public function getSession() /** * Whether the request contains a Session which was started in one of the * previous requests. - * - * @return bool */ - public function hasPreviousSession() + public function hasPreviousSession(): bool { // the check for $this->session avoids malicious users trying to fake a session cookie with proper name return $this->hasSession() && $this->cookies->has($this->getSession()->getName()); @@ -752,11 +722,11 @@ public function hasPreviousSession() * like whether the session is started or not. It is just a way to check if this Request * is associated with a Session instance. * - * @return bool true when the Request contains a Session object, false otherwise + * @param bool $skipIfUninitialized When true, ignores factories injected by `setSessionFactory` */ - public function hasSession() + public function hasSession(bool $skipIfUninitialized = false): bool { - return null !== $this->session; + return null !== $this->session && (!$skipIfUninitialized || $this->session instanceof SessionInterface); } public function setSession(SessionInterface $session) @@ -766,6 +736,8 @@ public function setSession(SessionInterface $session) /** * @internal + * + * @param callable(): SessionInterface $factory */ public function setSessionFactory(callable $factory) { @@ -781,11 +753,9 @@ public function setSessionFactory(callable $factory) * * Use this method carefully; you should use getClientIp() instead. * - * @return array The client IP addresses - * * @see getClientIp() */ - public function getClientIps() + public function getClientIps(): array { $ip = $this->server->get('REMOTE_ADDR'); @@ -809,12 +779,10 @@ public function getClientIps() * ("Client-Ip" for instance), configure it via the $trustedHeaderSet * argument of the Request::setTrustedProxies() method instead. * - * @return string|null The client IP address - * * @see getClientIps() * @see https://wikipedia.org/wiki/X-Forwarded-For */ - public function getClientIp() + public function getClientIp(): ?string { $ipAddresses = $this->getClientIps(); @@ -823,10 +791,8 @@ public function getClientIp() /** * Returns current script name. - * - * @return string */ - public function getScriptName() + public function getScriptName(): string { return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', '')); } @@ -845,7 +811,7 @@ public function getScriptName() * * @return string The raw path (i.e. not urldecoded) */ - public function getPathInfo() + public function getPathInfo(): string { if (null === $this->pathInfo) { $this->pathInfo = $this->preparePathInfo(); @@ -866,7 +832,7 @@ public function getPathInfo() * * @return string The raw path (i.e. not urldecoded) */ - public function getBasePath() + public function getBasePath(): string { if (null === $this->basePath) { $this->basePath = $this->prepareBasePath(); @@ -885,7 +851,25 @@ public function getBasePath() * * @return string The raw URL (i.e. not urldecoded) */ - public function getBaseUrl() + public function getBaseUrl(): string + { + $trustedPrefix = ''; + + // the proxy prefix must be prepended to any prefix being needed at the webserver level + if ($this->isFromTrustedProxy() && $trustedPrefixValues = $this->getTrustedValues(self::HEADER_X_FORWARDED_PREFIX)) { + $trustedPrefix = rtrim($trustedPrefixValues[0], '/'); + } + + return $trustedPrefix.$this->getBaseUrlReal(); + } + + /** + * Returns the real base URL received by the webserver from which this request is executed. + * The URL does not include trusted reverse proxy prefix. + * + * @return string The raw URL (i.e. not urldecoded) + */ + private function getBaseUrlReal(): string { if (null === $this->baseUrl) { $this->baseUrl = $this->prepareBaseUrl(); @@ -896,10 +880,8 @@ public function getBaseUrl() /** * Gets the request's scheme. - * - * @return string */ - public function getScheme() + public function getScheme(): string { return $this->isSecure() ? 'https' : 'http'; } @@ -912,9 +894,9 @@ public function getScheme() * * The "X-Forwarded-Port" header must contain the client port. * - * @return int|string can be a string if fetched from the server bag + * @return int|string|null Can be a string if fetched from the server bag */ - public function getPort() + public function getPort(): int|string|null { if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_PORT)) { $host = $host[0]; @@ -939,20 +921,16 @@ public function getPort() /** * Returns the user. - * - * @return string|null */ - public function getUser() + public function getUser(): ?string { return $this->headers->get('PHP_AUTH_USER'); } /** * Returns the password. - * - * @return string|null */ - public function getPassword() + public function getPassword(): ?string { return $this->headers->get('PHP_AUTH_PW'); } @@ -960,9 +938,9 @@ public function getPassword() /** * Gets the user info. * - * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server + * @return string|null A user name if any and, optionally, scheme-specific information about how to gain authorization to access the server */ - public function getUserInfo() + public function getUserInfo(): ?string { $userinfo = $this->getUser(); @@ -978,10 +956,8 @@ public function getUserInfo() * Returns the HTTP host being requested. * * The port name will be appended to the host if it's non-standard. - * - * @return string */ - public function getHttpHost() + public function getHttpHost(): string { $scheme = $this->getScheme(); $port = $this->getPort(); @@ -998,7 +974,7 @@ public function getHttpHost() * * @return string The raw URI (i.e. not URI decoded) */ - public function getRequestUri() + public function getRequestUri(): string { if (null === $this->requestUri) { $this->requestUri = $this->prepareRequestUri(); @@ -1012,10 +988,8 @@ public function getRequestUri() * * If the URL was called with basic authentication, the user * and the password are not added to the generated string. - * - * @return string The scheme and HTTP host */ - public function getSchemeAndHttpHost() + public function getSchemeAndHttpHost(): string { return $this->getScheme().'://'.$this->getHttpHost(); } @@ -1023,11 +997,9 @@ public function getSchemeAndHttpHost() /** * Generates a normalized URI (URL) for the Request. * - * @return string A normalized URI (URL) for the Request - * * @see getQueryString() */ - public function getUri() + public function getUri(): string { if (null !== $qs = $this->getQueryString()) { $qs = '?'.$qs; @@ -1040,10 +1012,8 @@ public function getUri() * Generates a normalized URI for the given path. * * @param string $path A path to use instead of the current one - * - * @return string The normalized URI for the path */ - public function getUriForPath(string $path) + public function getUriForPath(string $path): string { return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path; } @@ -1062,10 +1032,8 @@ public function getUriForPath(string $path) * - "/a/b/" -> "../" * - "/a/b/c/other" -> "other" * - "/a/x/y" -> "../../x/y" - * - * @return string The relative target path */ - public function getRelativeUriForPath(string $path) + public function getRelativeUriForPath(string $path): string { // be sure that we are dealing with an absolute path if (!isset($path[0]) || '/' !== $path[0]) { @@ -1106,10 +1074,8 @@ public function getRelativeUriForPath(string $path) * * It builds a normalized query string, where keys/value pairs are alphabetized * and have consistent escaping. - * - * @return string|null A normalized query string for the Request */ - public function getQueryString() + public function getQueryString(): ?string { $qs = static::normalizeQueryString($this->server->get('QUERY_STRING')); @@ -1123,10 +1089,8 @@ public function getQueryString() * when trusted proxies were set via "setTrustedProxies()". * * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http". - * - * @return bool */ - public function isSecure() + public function isSecure(): bool { if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_X_FORWARDED_PROTO)) { return \in_array(strtolower($proto[0]), ['https', 'on', 'ssl', '1'], true); @@ -1145,11 +1109,9 @@ public function isSecure() * * The "X-Forwarded-Host" header must contain the client host name. * - * @return string - * * @throws SuspiciousOperationException when the host name is invalid or not trusted */ - public function getHost() + public function getHost(): string { if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_HOST)) { $host = $host[0]; @@ -1221,11 +1183,9 @@ public function setMethod(string $method) * * The method is always an uppercased string. * - * @return string The request method - * * @see getRealMethod() */ - public function getMethod() + public function getMethod(): string { if (null !== $this->method) { return $this->method; @@ -1263,21 +1223,17 @@ public function getMethod() /** * Gets the "real" request method. * - * @return string The request method - * * @see getMethod() */ - public function getRealMethod() + public function getRealMethod(): string { return strtoupper($this->server->get('REQUEST_METHOD', 'GET')); } /** * Gets the mime type associated with the format. - * - * @return string|null The associated mime type (null if not found) */ - public function getMimeType(string $format) + public function getMimeType(string $format): ?string { if (null === static::$formats) { static::initializeFormats(); @@ -1288,27 +1244,23 @@ public function getMimeType(string $format) /** * Gets the mime types associated with the format. - * - * @return array The associated mime types */ - public static function getMimeTypes(string $format) + public static function getMimeTypes(string $format): array { if (null === static::$formats) { static::initializeFormats(); } - return isset(static::$formats[$format]) ? static::$formats[$format] : []; + return static::$formats[$format] ?? []; } /** * Gets the format associated with the mime type. - * - * @return string|null The format (null if not found) */ - public function getFormat(?string $mimeType) + public function getFormat(?string $mimeType): ?string { $canonicalMimeType = null; - if (false !== $pos = strpos($mimeType, ';')) { + if ($mimeType && false !== $pos = strpos($mimeType, ';')) { $canonicalMimeType = trim(substr($mimeType, 0, $pos)); } @@ -1333,7 +1285,7 @@ public function getFormat(?string $mimeType) * * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type) */ - public function setFormat(?string $format, $mimeTypes) + public function setFormat(?string $format, string|array $mimeTypes) { if (null === static::$formats) { static::initializeFormats(); @@ -1352,16 +1304,14 @@ public function setFormat(?string $format, $mimeTypes) * * $default * * @see getPreferredFormat - * - * @return string|null The request format */ - public function getRequestFormat(?string $default = 'html') + public function getRequestFormat(?string $default = 'html'): ?string { if (null === $this->format) { $this->format = $this->attributes->get('_format'); } - return null === $this->format ? $default : $this->format; + return $this->format ?? $default; } /** @@ -1374,12 +1324,10 @@ public function setRequestFormat(?string $format) /** * Gets the format associated with the request. - * - * @return string|null The format (null if no content type is present) */ - public function getContentType() + public function getContentType(): ?string { - return $this->getFormat($this->headers->get('CONTENT_TYPE')); + return $this->getFormat($this->headers->get('CONTENT_TYPE', '')); } /** @@ -1396,10 +1344,8 @@ public function setDefaultLocale(string $locale) /** * Get the default locale. - * - * @return string */ - public function getDefaultLocale() + public function getDefaultLocale(): string { return $this->defaultLocale; } @@ -1414,10 +1360,8 @@ public function setLocale(string $locale) /** * Get the locale. - * - * @return string */ - public function getLocale() + public function getLocale(): string { return null === $this->locale ? $this->defaultLocale : $this->locale; } @@ -1426,10 +1370,8 @@ public function getLocale() * Checks if the request method is of specified type. * * @param string $method Uppercase request method (GET, POST etc) - * - * @return bool */ - public function isMethod(string $method) + public function isMethod(string $method): bool { return $this->getMethod() === strtoupper($method); } @@ -1438,20 +1380,16 @@ public function isMethod(string $method) * Checks whether or not the method is safe. * * @see https://tools.ietf.org/html/rfc7231#section-4.2.1 - * - * @return bool */ - public function isMethodSafe() + public function isMethodSafe(): bool { return \in_array($this->getMethod(), ['GET', 'HEAD', 'OPTIONS', 'TRACE']); } /** * Checks whether or not the method is idempotent. - * - * @return bool */ - public function isMethodIdempotent() + public function isMethodIdempotent(): bool { return \in_array($this->getMethod(), ['HEAD', 'GET', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'PURGE']); } @@ -1460,10 +1398,8 @@ public function isMethodIdempotent() * Checks whether the method is cacheable or not. * * @see https://tools.ietf.org/html/rfc7231#section-4.2.3 - * - * @return bool True for GET and HEAD, false otherwise */ - public function isMethodCacheable() + public function isMethodCacheable(): bool { return \in_array($this->getMethod(), ['GET', 'HEAD']); } @@ -1476,13 +1412,11 @@ public function isMethodCacheable() * server might be different. This returns the former (from the "Via" header) * if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns * the latter (from the "SERVER_PROTOCOL" server parameter). - * - * @return string */ - public function getProtocolVersion() + public function getProtocolVersion(): ?string { if ($this->isFromTrustedProxy()) { - preg_match('~^(HTTP/)?([1-9]\.[0-9]) ~', $this->headers->get('Via'), $matches); + preg_match('~^(HTTP/)?([1-9]\.[0-9]) ~', $this->headers->get('Via') ?? '', $matches); if ($matches) { return 'HTTP/'.$matches[2]; @@ -1497,9 +1431,7 @@ public function getProtocolVersion() * * @param bool $asResource If true, a resource will be returned * - * @return string|resource The request body content or a resource to read the body stream - * - * @throws \LogicException + * @return string|resource */ public function getContent(bool $asResource = false) { @@ -1523,7 +1455,7 @@ public function getContent(bool $asResource = false) $this->content = false; - return fopen('php://input', 'rb'); + return fopen('php://input', 'r'); } if ($currentContentIsResource) { @@ -1540,27 +1472,46 @@ public function getContent(bool $asResource = false) } /** - * Gets the Etags. + * Gets the request body decoded as array, typically from a JSON payload. * - * @return array The entity tags + * @throws JsonException When the body cannot be decoded to an array */ - public function getETags() + public function toArray(): array { - return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY); + if ('' === $content = $this->getContent()) { + throw new JsonException('Request body is empty.'); + } + + try { + $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | \JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { + throw new JsonException('Could not decode request body.', $e->getCode(), $e); + } + + if (!\is_array($content)) { + throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content))); + } + + return $content; } /** - * @return bool + * Gets the Etags. */ - public function isNoCache() + public function getETags(): array + { + return preg_split('/\s*,\s*/', $this->headers->get('If-None-Match', ''), -1, \PREG_SPLIT_NO_EMPTY); + } + + public function isNoCache(): bool { return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma'); } /** * Gets the preferred format for the response by inspecting, in the following order: - * * the request format set using setRequestFormat - * * the values of the Accept HTTP header + * * the request format set using setRequestFormat; + * * the values of the Accept HTTP header. * * Note that if you use this method, you should send the "Vary: Accept" header * in the response to prevent any issues with intermediary HTTP caches. @@ -1584,15 +1535,13 @@ public function getPreferredFormat(?string $default = 'html'): ?string * Returns the preferred language. * * @param string[] $locales An array of ordered available locales - * - * @return string|null The preferred locale */ - public function getPreferredLanguage(array $locales = null) + public function getPreferredLanguage(array $locales = null): ?string { $preferredLanguages = $this->getLanguages(); if (empty($locales)) { - return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null; + return $preferredLanguages[0] ?? null; } if (!$preferredLanguages) { @@ -1612,15 +1561,13 @@ public function getPreferredLanguage(array $locales = null) $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales)); - return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0]; + return $preferredLanguages[0] ?? $locales[0]; } /** - * Gets a list of languages acceptable by the client browser. - * - * @return array Languages ordered in the user browser preferences + * Gets a list of languages acceptable by the client browser ordered in the user browser preferences. */ - public function getLanguages() + public function getLanguages(): array { if (null !== $this->languages) { return $this->languages; @@ -1628,8 +1575,9 @@ public function getLanguages() $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); $this->languages = []; - foreach ($languages as $lang => $acceptHeaderItem) { - if (false !== strpos($lang, '-')) { + foreach ($languages as $acceptHeaderItem) { + $lang = $acceptHeaderItem->getValue(); + if (str_contains($lang, '-')) { $codes = explode('-', $lang); if ('i' === $codes[0]) { // Language not listed in ISO 639 that are not variants @@ -1656,62 +1604,73 @@ public function getLanguages() } /** - * Gets a list of charsets acceptable by the client browser. - * - * @return array List of charsets in preferable order + * Gets a list of charsets acceptable by the client browser in preferable order. */ - public function getCharsets() + public function getCharsets(): array { if (null !== $this->charsets) { return $this->charsets; } - return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all()); + return $this->charsets = array_map('strval', array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all())); } /** - * Gets a list of encodings acceptable by the client browser. - * - * @return array List of encodings in preferable order + * Gets a list of encodings acceptable by the client browser in preferable order. */ - public function getEncodings() + public function getEncodings(): array { if (null !== $this->encodings) { return $this->encodings; } - return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all()); + return $this->encodings = array_map('strval', array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all())); } /** - * Gets a list of content types acceptable by the client browser. - * - * @return array List of content types in preferable order + * Gets a list of content types acceptable by the client browser in preferable order. */ - public function getAcceptableContentTypes() + public function getAcceptableContentTypes(): array { if (null !== $this->acceptableContentTypes) { return $this->acceptableContentTypes; } - return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all()); + return $this->acceptableContentTypes = array_map('strval', array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all())); } /** - * Returns true if the request is a XMLHttpRequest. + * Returns true if the request is an XMLHttpRequest. * * It works if your JavaScript library sets an X-Requested-With HTTP header. * It is known to work with common JavaScript frameworks: * * @see https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript - * - * @return bool true if the request is an XMLHttpRequest, false otherwise */ - public function isXmlHttpRequest() + public function isXmlHttpRequest(): bool { return 'XMLHttpRequest' == $this->headers->get('X-Requested-With'); } + /** + * Checks whether the client browser prefers safe content or not according to RFC8674. + * + * @see https://tools.ietf.org/html/rfc8674 + */ + public function preferSafeContent(): bool + { + if (isset($this->isSafeContentPreferred)) { + return $this->isSafeContentPreferred; + } + + if (!$this->isSecure()) { + // see https://tools.ietf.org/html/rfc8674#section-3 + return $this->isSafeContentPreferred = false; + } + + return $this->isSafeContentPreferred = AcceptHeader::fromString($this->headers->get('Prefer'))->has('safe'); + } + /* * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24) * @@ -1767,18 +1726,16 @@ protected function prepareRequestUri() /** * Prepares the base URL. - * - * @return string */ - protected function prepareBaseUrl() + protected function prepareBaseUrl(): string { - $filename = basename($this->server->get('SCRIPT_FILENAME')); + $filename = basename($this->server->get('SCRIPT_FILENAME', '')); - if (basename($this->server->get('SCRIPT_NAME')) === $filename) { + if (basename($this->server->get('SCRIPT_NAME', '')) === $filename) { $baseUrl = $this->server->get('SCRIPT_NAME'); - } elseif (basename($this->server->get('PHP_SELF')) === $filename) { + } elseif (basename($this->server->get('PHP_SELF', '')) === $filename) { $baseUrl = $this->server->get('PHP_SELF'); - } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) { + } elseif (basename($this->server->get('ORIG_SCRIPT_NAME', '')) === $filename) { $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility } else { // Backtrack up the script_filename to find the portion matching @@ -1818,7 +1775,7 @@ protected function prepareBaseUrl() $truncatedRequestUri = substr($requestUri, 0, $pos); } - $basename = basename($baseUrl); + $basename = basename($baseUrl ?? ''); if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { // no match whatsoever; set it blank return ''; @@ -1836,10 +1793,8 @@ protected function prepareBaseUrl() /** * Prepares the base path. - * - * @return string base path */ - protected function prepareBasePath() + protected function prepareBasePath(): string { $baseUrl = $this->getBaseUrl(); if (empty($baseUrl)) { @@ -1862,10 +1817,8 @@ protected function prepareBasePath() /** * Prepares the path info. - * - * @return string path info */ - protected function preparePathInfo() + protected function preparePathInfo(): string { if (null === ($requestUri = $this->getRequestUri())) { return '/'; @@ -1879,7 +1832,7 @@ protected function preparePathInfo() $requestUri = '/'.$requestUri; } - if (null === ($baseUrl = $this->getBaseUrl())) { + if (null === ($baseUrl = $this->getBaseUrlReal())) { return $requestUri; } @@ -1889,7 +1842,7 @@ protected function preparePathInfo() return '/'; } - return (string) $pathInfo; + return $pathInfo; } /** @@ -1908,7 +1861,7 @@ protected static function initializeFormats() 'rdf' => ['application/rdf+xml'], 'atom' => ['application/atom+xml'], 'rss' => ['application/rss+xml'], - 'form' => ['application/x-www-form-urlencoded'], + 'form' => ['application/x-www-form-urlencoded', 'multipart/form-data'], ]; } @@ -1918,7 +1871,7 @@ private function setPhpDefaultLocale(string $locale): void // setting the default locale, the intl module is not installed, and // the call can be ignored: try { - if (class_exists('Locale', false)) { + if (class_exists(\Locale::class, false)) { \Locale::setDefault($locale); } } catch (\Exception $e) { @@ -1931,7 +1884,7 @@ private function setPhpDefaultLocale(string $locale): void */ private function getUrlencodedPrefix(string $string, string $prefix): ?string { - if (0 !== strpos(rawurldecode($string), $prefix)) { + if (!str_starts_with(rawurldecode($string), $prefix)) { return null; } @@ -1944,7 +1897,7 @@ private function getUrlencodedPrefix(string $string, string $prefix): ?string return null; } - private static function createRequestFromFactory(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): self + private static function createRequestFromFactory(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): static { if (self::$requestFactory) { $request = (self::$requestFactory)($query, $request, $attributes, $cookies, $files, $server, $content); @@ -1964,12 +1917,10 @@ private static function createRequestFromFactory(array $query = [], array $reque * * This can be useful to determine whether or not to trust the * contents of a proxy-specific header. - * - * @return bool true if the request came from a trusted proxy, false otherwise */ - public function isFromTrustedProxy() + public function isFromTrustedProxy(): bool { - return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); + return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR', ''), self::$trustedProxies); } private function getTrustedValues(int $type, string $ip = null): array @@ -1977,23 +1928,23 @@ private function getTrustedValues(int $type, string $ip = null): array $clientValues = []; $forwardedValues = []; - if ((self::$trustedHeaderSet & $type) && $this->headers->has(self::$trustedHeaders[$type])) { - foreach (explode(',', $this->headers->get(self::$trustedHeaders[$type])) as $v) { + if ((self::$trustedHeaderSet & $type) && $this->headers->has(self::TRUSTED_HEADERS[$type])) { + foreach (explode(',', $this->headers->get(self::TRUSTED_HEADERS[$type])) as $v) { $clientValues[] = (self::HEADER_X_FORWARDED_PORT === $type ? '0.0.0.0:' : '').trim($v); } } - if ((self::$trustedHeaderSet & self::HEADER_FORWARDED) && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { - $forwarded = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); + if ((self::$trustedHeaderSet & self::HEADER_FORWARDED) && (isset(self::FORWARDED_PARAMS[$type])) && $this->headers->has(self::TRUSTED_HEADERS[self::HEADER_FORWARDED])) { + $forwarded = $this->headers->get(self::TRUSTED_HEADERS[self::HEADER_FORWARDED]); $parts = HeaderUtils::split($forwarded, ',;='); $forwardedValues = []; - $param = self::$forwardedParams[$type]; + $param = self::FORWARDED_PARAMS[$type]; foreach ($parts as $subParts) { if (null === $v = HeaderUtils::combine($subParts)[$param] ?? null) { continue; } if (self::HEADER_X_FORWARDED_PORT === $type) { - if (']' === substr($v, -1) || false === $v = strrchr($v, ':')) { + if (str_ends_with($v, ']') || false === $v = strrchr($v, ':')) { $v = $this->isSecure() ? ':443' : ':80'; } $v = '0.0.0.0'.$v; @@ -2020,7 +1971,7 @@ private function getTrustedValues(int $type, string $ip = null): array } $this->isForwardedValid = false; - throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::$trustedHeaders[self::HEADER_FORWARDED], self::$trustedHeaders[$type])); + throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::TRUSTED_HEADERS[self::HEADER_FORWARDED], self::TRUSTED_HEADERS[$type])); } private function normalizeAndFilterClientIps(array $clientIps, string $ip): array @@ -2039,13 +1990,13 @@ private function normalizeAndFilterClientIps(array $clientIps, string $ip): arra if ($i) { $clientIps[$key] = $clientIp = substr($clientIp, 0, $i); } - } elseif (0 === strpos($clientIp, '[')) { + } elseif (str_starts_with($clientIp, '[')) { // Strip brackets and :port from IPv6 addresses. $i = strpos($clientIp, ']', 1); $clientIps[$key] = $clientIp = substr($clientIp, 1, $i - 1); } - if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { + if (!filter_var($clientIp, \FILTER_VALIDATE_IP)) { unset($clientIps[$key]); continue; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcher.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcher.php index c32c5cdce..91dcdd51c 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcher.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcher.php @@ -18,47 +18,36 @@ */ class RequestMatcher implements RequestMatcherInterface { - /** - * @var string|null - */ - private $path; - - /** - * @var string|null - */ - private $host; - - /** - * @var int|null - */ - private $port; + private ?string $path = null; + private ?string $host = null; + private ?int $port = null; /** * @var string[] */ - private $methods = []; + private array $methods = []; /** * @var string[] */ - private $ips = []; + private array $ips = []; /** - * @var array + * @var string[] */ - private $attributes = []; + private array $attributes = []; /** * @var string[] */ - private $schemes = []; + private array $schemes = []; /** * @param string|string[]|null $methods * @param string|string[]|null $ips * @param string|string[]|null $schemes */ - public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = [], $schemes = null, int $port = null) + public function __construct(string $path = null, string $host = null, string|array $methods = null, string|array $ips = null, array $attributes = [], string|array $schemes = null, int $port = null) { $this->matchPath($path); $this->matchHost($host); @@ -77,7 +66,7 @@ public function __construct(string $path = null, string $host = null, $methods = * * @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes */ - public function matchScheme($scheme) + public function matchScheme(string|array|null $scheme) { $this->schemes = null !== $scheme ? array_map('strtolower', (array) $scheme) : []; } @@ -123,9 +112,13 @@ public function matchIp(string $ip) * * @param string|string[]|null $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24 */ - public function matchIps($ips) + public function matchIps(string|array|null $ips) { - $this->ips = null !== $ips ? (array) $ips : []; + $ips = null !== $ips ? (array) $ips : []; + + $this->ips = array_reduce($ips, static function (array $ips, string $ip) { + return array_merge($ips, preg_split('/\s*,\s*/', $ip)); + }, []); } /** @@ -133,7 +126,7 @@ public function matchIps($ips) * * @param string|string[]|null $method An HTTP method or an array of HTTP methods */ - public function matchMethod($method) + public function matchMethod(string|array|null $method) { $this->methods = null !== $method ? array_map('strtoupper', (array) $method) : []; } @@ -149,7 +142,7 @@ public function matchAttribute(string $key, string $regexp) /** * {@inheritdoc} */ - public function matches(Request $request) + public function matches(Request $request): bool { if ($this->schemes && !\in_array($request->getScheme(), $this->schemes, true)) { return false; @@ -160,7 +153,11 @@ public function matches(Request $request) } foreach ($this->attributes as $key => $pattern) { - if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) { + $requestAttribute = $request->attributes->get($key); + if (!\is_string($requestAttribute)) { + return false; + } + if (!preg_match('{'.$pattern.'}', $requestAttribute)) { return false; } } @@ -177,7 +174,7 @@ public function matches(Request $request) return false; } - if (IpUtils::checkIp($request->getClientIp(), $this->ips)) { + if (IpUtils::checkIp($request->getClientIp() ?? '', $this->ips)) { return true; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcherInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcherInterface.php index c26db3e6f..6dcc3e0fc 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcherInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestMatcherInterface.php @@ -20,8 +20,6 @@ interface RequestMatcherInterface { /** * Decides whether the rule(s) implemented by the strategy matches the supplied request. - * - * @return bool true if the request matches, false otherwise */ - public function matches(Request $request); + public function matches(Request $request): bool; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestStack.php b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestStack.php index 244a77d63..6b13fa1e6 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/RequestStack.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/RequestStack.php @@ -11,6 +11,9 @@ namespace Symfony\Component\HttpFoundation; +use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; +use Symfony\Component\HttpFoundation\Session\SessionInterface; + /** * Request stack that controls the lifecycle of requests. * @@ -21,7 +24,7 @@ class RequestStack /** * @var Request[] */ - private $requests = []; + private array $requests = []; /** * Pushes a Request on the stack. @@ -41,10 +44,8 @@ public function push(Request $request) * * This method should generally not be called directly as the stack * management should be taken care of by the application itself. - * - * @return Request|null */ - public function pop() + public function pop(): ?Request { if (!$this->requests) { return null; @@ -53,24 +54,19 @@ public function pop() return array_pop($this->requests); } - /** - * @return Request|null - */ - public function getCurrentRequest() + public function getCurrentRequest(): ?Request { return end($this->requests) ?: null; } /** - * Gets the master Request. + * Gets the main request. * - * Be warned that making your code aware of the master request + * Be warned that making your code aware of the main request * might make it un-compatible with other features of your framework * like ESI support. - * - * @return Request|null */ - public function getMasterRequest() + public function getMainRequest(): ?Request { if (!$this->requests) { return null; @@ -86,18 +82,26 @@ public function getMasterRequest() * might make it un-compatible with other features of your framework * like ESI support. * - * If current Request is the master request, it returns null. - * - * @return Request|null + * If current Request is the main request, it returns null. */ - public function getParentRequest() + public function getParentRequest(): ?Request { $pos = \count($this->requests) - 2; - if (!isset($this->requests[$pos])) { - return null; + return $this->requests[$pos] ?? null; + } + + /** + * Gets the current session. + * + * @throws SessionNotFoundException + */ + public function getSession(): SessionInterface + { + if ((null !== $request = end($this->requests) ?: null) && $request->hasSession()) { + return $request->getSession(); } - return $this->requests[$pos]; + throw new SessionNotFoundException(); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Response.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Response.php index 990bf0d5e..c48efdfb7 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Response.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Response.php @@ -21,69 +21,87 @@ class_exists(ResponseHeaderBag::class); */ class Response { - const HTTP_CONTINUE = 100; - const HTTP_SWITCHING_PROTOCOLS = 101; - const HTTP_PROCESSING = 102; // RFC2518 - const HTTP_EARLY_HINTS = 103; // RFC8297 - const HTTP_OK = 200; - const HTTP_CREATED = 201; - const HTTP_ACCEPTED = 202; - const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; - const HTTP_NO_CONTENT = 204; - const HTTP_RESET_CONTENT = 205; - const HTTP_PARTIAL_CONTENT = 206; - const HTTP_MULTI_STATUS = 207; // RFC4918 - const HTTP_ALREADY_REPORTED = 208; // RFC5842 - const HTTP_IM_USED = 226; // RFC3229 - const HTTP_MULTIPLE_CHOICES = 300; - const HTTP_MOVED_PERMANENTLY = 301; - const HTTP_FOUND = 302; - const HTTP_SEE_OTHER = 303; - const HTTP_NOT_MODIFIED = 304; - const HTTP_USE_PROXY = 305; - const HTTP_RESERVED = 306; - const HTTP_TEMPORARY_REDIRECT = 307; - const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238 - const HTTP_BAD_REQUEST = 400; - const HTTP_UNAUTHORIZED = 401; - const HTTP_PAYMENT_REQUIRED = 402; - const HTTP_FORBIDDEN = 403; - const HTTP_NOT_FOUND = 404; - const HTTP_METHOD_NOT_ALLOWED = 405; - const HTTP_NOT_ACCEPTABLE = 406; - const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; - const HTTP_REQUEST_TIMEOUT = 408; - const HTTP_CONFLICT = 409; - const HTTP_GONE = 410; - const HTTP_LENGTH_REQUIRED = 411; - const HTTP_PRECONDITION_FAILED = 412; - const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; - const HTTP_REQUEST_URI_TOO_LONG = 414; - const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; - const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - const HTTP_EXPECTATION_FAILED = 417; - const HTTP_I_AM_A_TEAPOT = 418; // RFC2324 - const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540 - const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918 - const HTTP_LOCKED = 423; // RFC4918 - const HTTP_FAILED_DEPENDENCY = 424; // RFC4918 - const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04 - const HTTP_UPGRADE_REQUIRED = 426; // RFC2817 - const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585 - const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585 - const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585 - const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; - const HTTP_INTERNAL_SERVER_ERROR = 500; - const HTTP_NOT_IMPLEMENTED = 501; - const HTTP_BAD_GATEWAY = 502; - const HTTP_SERVICE_UNAVAILABLE = 503; - const HTTP_GATEWAY_TIMEOUT = 504; - const HTTP_VERSION_NOT_SUPPORTED = 505; - const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295 - const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918 - const HTTP_LOOP_DETECTED = 508; // RFC5842 - const HTTP_NOT_EXTENDED = 510; // RFC2774 - const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585 + public const HTTP_CONTINUE = 100; + public const HTTP_SWITCHING_PROTOCOLS = 101; + public const HTTP_PROCESSING = 102; // RFC2518 + public const HTTP_EARLY_HINTS = 103; // RFC8297 + public const HTTP_OK = 200; + public const HTTP_CREATED = 201; + public const HTTP_ACCEPTED = 202; + public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; + public const HTTP_NO_CONTENT = 204; + public const HTTP_RESET_CONTENT = 205; + public const HTTP_PARTIAL_CONTENT = 206; + public const HTTP_MULTI_STATUS = 207; // RFC4918 + public const HTTP_ALREADY_REPORTED = 208; // RFC5842 + public const HTTP_IM_USED = 226; // RFC3229 + public const HTTP_MULTIPLE_CHOICES = 300; + public const HTTP_MOVED_PERMANENTLY = 301; + public const HTTP_FOUND = 302; + public const HTTP_SEE_OTHER = 303; + public const HTTP_NOT_MODIFIED = 304; + public const HTTP_USE_PROXY = 305; + public const HTTP_RESERVED = 306; + public const HTTP_TEMPORARY_REDIRECT = 307; + public const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238 + public const HTTP_BAD_REQUEST = 400; + public const HTTP_UNAUTHORIZED = 401; + public const HTTP_PAYMENT_REQUIRED = 402; + public const HTTP_FORBIDDEN = 403; + public const HTTP_NOT_FOUND = 404; + public const HTTP_METHOD_NOT_ALLOWED = 405; + public const HTTP_NOT_ACCEPTABLE = 406; + public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; + public const HTTP_REQUEST_TIMEOUT = 408; + public const HTTP_CONFLICT = 409; + public const HTTP_GONE = 410; + public const HTTP_LENGTH_REQUIRED = 411; + public const HTTP_PRECONDITION_FAILED = 412; + public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; + public const HTTP_REQUEST_URI_TOO_LONG = 414; + public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; + public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + public const HTTP_EXPECTATION_FAILED = 417; + public const HTTP_I_AM_A_TEAPOT = 418; // RFC2324 + public const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540 + public const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918 + public const HTTP_LOCKED = 423; // RFC4918 + public const HTTP_FAILED_DEPENDENCY = 424; // RFC4918 + public const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04 + public const HTTP_UPGRADE_REQUIRED = 426; // RFC2817 + public const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585 + public const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585 + public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585 + public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; // RFC7725 + public const HTTP_INTERNAL_SERVER_ERROR = 500; + public const HTTP_NOT_IMPLEMENTED = 501; + public const HTTP_BAD_GATEWAY = 502; + public const HTTP_SERVICE_UNAVAILABLE = 503; + public const HTTP_GATEWAY_TIMEOUT = 504; + public const HTTP_VERSION_NOT_SUPPORTED = 505; + public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295 + public const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918 + public const HTTP_LOOP_DETECTED = 508; // RFC5842 + public const HTTP_NOT_EXTENDED = 510; // RFC2774 + public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585 + + /** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + */ + private const HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES = [ + 'must_revalidate' => false, + 'no_cache' => false, + 'no_store' => false, + 'no_transform' => false, + 'public' => false, + 'private' => false, + 'proxy_revalidate' => false, + 'max_age' => true, + 's_maxage' => true, + 'immutable' => false, + 'last_modified' => true, + 'etag' => true, + ]; /** * @var ResponseHeaderBag @@ -120,7 +138,7 @@ class Response * * The list of codes is complete according to the * {@link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Hypertext Transfer Protocol (HTTP) Status Code Registry} - * (last updated 2016-03-01). + * (last updated 2021-10-01). * * Unless otherwise noted, the status code is defined in RFC2616. * @@ -162,14 +180,14 @@ class Response 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', - 413 => 'Payload Too Large', + 413 => 'Content Too Large', // RFC-ietf-httpbis-semantics 414 => 'URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', // RFC2324 421 => 'Misdirected Request', // RFC7540 - 422 => 'Unprocessable Entity', // RFC4918 + 422 => 'Unprocessable Content', // RFC-ietf-httpbis-semantics 423 => 'Locked', // RFC4918 424 => 'Failed Dependency', // RFC4918 425 => 'Too Early', // RFC-ietf-httpbis-replay-04 @@ -202,21 +220,6 @@ public function __construct(?string $content = '', int $status = 200, array $hea $this->setProtocolVersion('1.0'); } - /** - * Factory method for chainability. - * - * Example: - * - * return Response::create($body, 200) - * ->setSharedMaxAge(300); - * - * @return static - */ - public static function create(?string $content = '', int $status = 200, array $headers = []) - { - return new static($content, $status, $headers); - } - /** * Returns the Response as an HTTP string. * @@ -224,11 +227,9 @@ public static function create(?string $content = '', int $status = 200, array $h * one that will be sent to the client only if the prepare() method * has been called before. * - * @return string The Response as an HTTP string - * * @see prepare() */ - public function __toString() + public function __toString(): string { return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". @@ -253,7 +254,7 @@ public function __clone() * * @return $this */ - public function prepare(Request $request) + public function prepare(Request $request): static { $headers = $this->headers; @@ -302,7 +303,7 @@ public function prepare(Request $request) } // Check if we need to send extra expire info headers - if ('1.0' == $this->getProtocolVersion() && false !== strpos($headers->get('Cache-Control'), 'no-cache')) { + if ('1.0' == $this->getProtocolVersion() && str_contains($headers->get('Cache-Control', ''), 'no-cache')) { $headers->set('pragma', 'no-cache'); $headers->set('expires', -1); } @@ -323,7 +324,7 @@ public function prepare(Request $request) * * @return $this */ - public function sendHeaders() + public function sendHeaders(): static { // headers have already been sent by the developer if (headers_sent()) { @@ -354,7 +355,7 @@ public function sendHeaders() * * @return $this */ - public function sendContent() + public function sendContent(): static { echo $this->content; @@ -366,15 +367,18 @@ public function sendContent() * * @return $this */ - public function send() + public function send(): static { $this->sendHeaders(); $this->sendContent(); if (\function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); + } elseif (\function_exists('litespeed_finish_request')) { + litespeed_finish_request(); } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) { static::closeOutputBuffers(0, true); + flush(); } return $this; @@ -384,10 +388,8 @@ public function send() * Sets the response content. * * @return $this - * - * @throws \UnexpectedValueException */ - public function setContent(?string $content) + public function setContent(?string $content): static { $this->content = $content ?? ''; @@ -396,10 +398,8 @@ public function setContent(?string $content) /** * Gets the current response content. - * - * @return string|false */ - public function getContent() + public function getContent(): string|false { return $this->content; } @@ -411,7 +411,7 @@ public function getContent() * * @final */ - public function setProtocolVersion(string $version): object + public function setProtocolVersion(string $version): static { $this->version = $version; @@ -440,7 +440,7 @@ public function getProtocolVersion(): string * * @final */ - public function setStatusCode(int $code, $text = null): object + public function setStatusCode(int $code, string $text = null): static { $this->statusCode = $code; if ($this->isInvalid()) { @@ -448,7 +448,7 @@ public function setStatusCode(int $code, $text = null): object } if (null === $text) { - $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : 'unknown status'; + $this->statusText = self::$statusTexts[$code] ?? 'unknown status'; return $this; } @@ -481,7 +481,7 @@ public function getStatusCode(): int * * @final */ - public function setCharset(string $charset): object + public function setCharset(string $charset): static { $this->charset = $charset; @@ -562,7 +562,7 @@ public function isValidateable(): bool * * @final */ - public function setPrivate(): object + public function setPrivate(): static { $this->headers->removeCacheControlDirective('public'); $this->headers->addCacheControlDirective('private'); @@ -579,7 +579,7 @@ public function setPrivate(): object * * @final */ - public function setPublic(): object + public function setPublic(): static { $this->headers->addCacheControlDirective('public'); $this->headers->removeCacheControlDirective('private'); @@ -594,7 +594,7 @@ public function setPublic(): object * * @final */ - public function setImmutable(bool $immutable = true): object + public function setImmutable(bool $immutable = true): static { if ($immutable) { $this->headers->addCacheControlDirective('immutable'); @@ -649,7 +649,7 @@ public function getDate(): ?\DateTimeInterface * * @final */ - public function setDate(\DateTimeInterface $date): object + public function setDate(\DateTimeInterface $date): static { if ($date instanceof \DateTime) { $date = \DateTimeImmutable::createFromMutable($date); @@ -680,7 +680,7 @@ public function getAge(): int * * @return $this */ - public function expire() + public function expire(): static { if ($this->isFresh()) { $this->headers->set('Age', $this->getMaxAge()); @@ -714,7 +714,7 @@ public function getExpires(): ?\DateTimeInterface * * @final */ - public function setExpires(\DateTimeInterface $date = null): object + public function setExpires(\DateTimeInterface $date = null): static { if (null === $date) { $this->headers->remove('Expires'); @@ -767,7 +767,7 @@ public function getMaxAge(): ?int * * @final */ - public function setMaxAge(int $value): object + public function setMaxAge(int $value): static { $this->headers->addCacheControlDirective('max-age', $value); @@ -783,7 +783,7 @@ public function setMaxAge(int $value): object * * @final */ - public function setSharedMaxAge(int $value): object + public function setSharedMaxAge(int $value): static { $this->setPublic(); $this->headers->addCacheControlDirective('s-maxage', $value); @@ -817,7 +817,7 @@ public function getTtl(): ?int * * @final */ - public function setTtl(int $seconds): object + public function setTtl(int $seconds): static { $this->setSharedMaxAge($this->getAge() + $seconds); @@ -833,7 +833,7 @@ public function setTtl(int $seconds): object * * @final */ - public function setClientTtl(int $seconds): object + public function setClientTtl(int $seconds): static { $this->setMaxAge($this->getAge() + $seconds); @@ -861,7 +861,7 @@ public function getLastModified(): ?\DateTimeInterface * * @final */ - public function setLastModified(\DateTimeInterface $date = null): object + public function setLastModified(\DateTimeInterface $date = null): static { if (null === $date) { $this->headers->remove('Last-Modified'); @@ -899,12 +899,12 @@ public function getEtag(): ?string * * @final */ - public function setEtag(string $etag = null, bool $weak = false): object + public function setEtag(string $etag = null, bool $weak = false): static { if (null === $etag) { $this->headers->remove('Etag'); } else { - if (0 !== strpos($etag, '"')) { + if (!str_starts_with($etag, '"')) { $etag = '"'.$etag.'"'; } @@ -917,7 +917,7 @@ public function setEtag(string $etag = null, bool $weak = false): object /** * Sets the response's cache headers (validation and/or expiration). * - * Available options are: etag, last_modified, max_age, s_maxage, private, public and immutable. + * Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag. * * @return $this * @@ -925,9 +925,9 @@ public function setEtag(string $etag = null, bool $weak = false): object * * @final */ - public function setCache(array $options): object + public function setCache(array $options): static { - if ($diff = array_diff(array_keys($options), ['etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'])) { + if ($diff = array_diff(array_keys($options), array_keys(self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES))) { throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff))); } @@ -947,6 +947,16 @@ public function setCache(array $options): object $this->setSharedMaxAge($options['s_maxage']); } + foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) { + if (!$hasValue && isset($options[$directive])) { + if ($options[$directive]) { + $this->headers->addCacheControlDirective(str_replace('_', '-', $directive)); + } else { + $this->headers->removeCacheControlDirective(str_replace('_', '-', $directive)); + } + } + } + if (isset($options['public'])) { if ($options['public']) { $this->setPublic(); @@ -963,10 +973,6 @@ public function setCache(array $options): object } } - if (isset($options['immutable'])) { - $this->setImmutable((bool) $options['immutable']); - } - return $this; } @@ -982,7 +988,7 @@ public function setCache(array $options): object * * @final */ - public function setNotModified(): object + public function setNotModified(): static { $this->setStatusCode(304); $this->setContent(null); @@ -1018,23 +1024,22 @@ public function getVary(): array $ret = []; foreach ($vary as $item) { - $ret = array_merge($ret, preg_split('/[\s,]+/', $item)); + $ret[] = preg_split('/[\s,]+/', $item); } - return $ret; + return array_merge([], ...$ret); } /** * Sets the Vary header. * - * @param string|array $headers - * @param bool $replace Whether to replace the actual value or not (true by default) + * @param bool $replace Whether to replace the actual value or not (true by default) * * @return $this * * @final */ - public function setVary($headers, bool $replace = true): object + public function setVary(string|array $headers, bool $replace = true): static { $this->headers->set('Vary', $headers, $replace); @@ -1048,8 +1053,6 @@ public function setVary($headers, bool $replace = true): object * If the Response is not modified, it sets the status code to 304 and * removes the actual content by calling the setNotModified() method. * - * @return bool true if the Response validators match the Request, false otherwise - * * @final */ public function isNotModified(Request $request): bool @@ -1062,12 +1065,26 @@ public function isNotModified(Request $request): bool $lastModified = $this->headers->get('Last-Modified'); $modifiedSince = $request->headers->get('If-Modified-Since'); - if ($etags = $request->getETags()) { - $notModified = \in_array($this->getEtag(), $etags) || \in_array('*', $etags); - } + if (($ifNoneMatchEtags = $request->getETags()) && (null !== $etag = $this->getEtag())) { + if (0 == strncmp($etag, 'W/', 2)) { + $etag = substr($etag, 2); + } - if ($modifiedSince && $lastModified) { - $notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified); + // Use weak comparison as per https://tools.ietf.org/html/rfc7232#section-3.2. + foreach ($ifNoneMatchEtags as $ifNoneMatchEtag) { + if (0 == strncmp($ifNoneMatchEtag, 'W/', 2)) { + $ifNoneMatchEtag = substr($ifNoneMatchEtag, 2); + } + + if ($ifNoneMatchEtag === $etag || '*' === $ifNoneMatchEtag) { + $notModified = true; + break; + } + } + } + // Only do If-Modified-Since date comparison when If-None-Match is not present as per https://tools.ietf.org/html/rfc7232#section-3.3. + elseif ($modifiedSince && $lastModified) { + $notModified = strtotime($modifiedSince) >= strtotime($lastModified); } if ($notModified) { @@ -1200,7 +1217,7 @@ public static function closeOutputBuffers(int $targetLevel, bool $flush): void { $status = ob_get_status(true); $level = \count($status); - $flags = PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE); + $flags = \PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? \PHP_OUTPUT_HANDLER_FLUSHABLE : \PHP_OUTPUT_HANDLER_CLEANABLE); while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) { if ($flush) { @@ -1211,6 +1228,22 @@ public static function closeOutputBuffers(int $targetLevel, bool $flush): void } } + /** + * Marks a response as safe according to RFC8674. + * + * @see https://tools.ietf.org/html/rfc8674 + */ + public function setContentSafe(bool $safe = true): void + { + if ($safe) { + $this->headers->set('Preference-Applied', 'safe'); + } elseif ('safe' === $this->headers->get('Preference-Applied')) { + $this->headers->remove('Preference-Applied'); + } + + $this->setVary('Prefer', false); + } + /** * Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9. * @@ -1220,7 +1253,7 @@ public static function closeOutputBuffers(int $targetLevel, bool $flush): void */ protected function ensureIEOverSSLCompatibility(Request $request): void { - if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) && true === $request->isSecure()) { + if (false !== stripos($this->headers->get('Content-Disposition') ?? '', 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT') ?? '', $match) && true === $request->isSecure()) { if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) { $this->headers->remove('Cache-Control'); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/ResponseHeaderBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/ResponseHeaderBag.php index 5acefc9c9..2e2717416 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/ResponseHeaderBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/ResponseHeaderBag.php @@ -18,11 +18,11 @@ */ class ResponseHeaderBag extends HeaderBag { - const COOKIES_FLAT = 'flat'; - const COOKIES_ARRAY = 'array'; + public const COOKIES_FLAT = 'flat'; + public const COOKIES_ARRAY = 'array'; - const DISPOSITION_ATTACHMENT = 'attachment'; - const DISPOSITION_INLINE = 'inline'; + public const DISPOSITION_ATTACHMENT = 'attachment'; + public const DISPOSITION_INLINE = 'inline'; protected $computedCacheControl = []; protected $cookies = []; @@ -44,10 +44,8 @@ public function __construct(array $headers = []) /** * Returns the headers, with original capitalizations. - * - * @return array An array of headers */ - public function allPreserveCase() + public function allPreserveCase(): array { $headers = []; foreach ($this->all() as $name => $value) { @@ -88,7 +86,7 @@ public function replace(array $headers = []) /** * {@inheritdoc} */ - public function all(string $key = null) + public function all(string $key = null): array { $headers = parent::all(); @@ -108,7 +106,7 @@ public function all(string $key = null) /** * {@inheritdoc} */ - public function set(string $key, $values, bool $replace = true) + public function set(string $key, string|array|null $values, bool $replace = true) { $uniqueKey = strtr($key, self::UPPER, self::LOWER); @@ -164,7 +162,7 @@ public function remove(string $key) /** * {@inheritdoc} */ - public function hasCacheControlDirective(string $key) + public function hasCacheControlDirective(string $key): bool { return \array_key_exists($key, $this->computedCacheControl); } @@ -172,9 +170,9 @@ public function hasCacheControlDirective(string $key) /** * {@inheritdoc} */ - public function getCacheControlDirective(string $key) + public function getCacheControlDirective(string $key): bool|string|null { - return \array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; + return $this->computedCacheControl[$key] ?? null; } public function setCookie(Cookie $cookie) @@ -214,7 +212,7 @@ public function removeCookie(string $name, ?string $path = '/', string $domain = * * @throws \InvalidArgumentException When the $format is invalid */ - public function getCookies(string $format = self::COOKIES_FLAT) + public function getCookies(string $format = self::COOKIES_FLAT): array { if (!\in_array($format, [self::COOKIES_FLAT, self::COOKIES_ARRAY])) { throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', [self::COOKIES_FLAT, self::COOKIES_ARRAY]))); @@ -257,10 +255,8 @@ public function makeDisposition(string $disposition, string $filename, string $f * * This considers several other headers and calculates or modifies the * cache-control header to a sensible, conservative value. - * - * @return string */ - protected function computeCacheControlValue() + protected function computeCacheControlValue(): string { if (!$this->cacheControl) { if ($this->has('Last-Modified') || $this->has('Expires')) { @@ -286,8 +282,6 @@ protected function computeCacheControlValue() private function initDate(): void { - $now = \DateTime::createFromFormat('U', time()); - $now->setTimezone(new \DateTimeZone('UTC')); - $this->set('Date', $now->format('D, d M Y H:i:s').' GMT'); + $this->set('Date', gmdate('D, d M Y H:i:s').' GMT'); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/ServerBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/ServerBag.php index 02c70911c..5b0fc8ac4 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/ServerBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/ServerBag.php @@ -22,14 +22,12 @@ class ServerBag extends ParameterBag { /** * Gets the HTTP headers. - * - * @return array */ - public function getHeaders() + public function getHeaders(): array { $headers = []; foreach ($this->parameters as $key => $value) { - if (0 === strpos($key, 'HTTP_')) { + if (str_starts_with($key, 'HTTP_')) { $headers[substr($key, 5)] = $value; } elseif (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) { $headers[$key] = $value; @@ -38,7 +36,7 @@ public function getHeaders() if (isset($this->parameters['PHP_AUTH_USER'])) { $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER']; - $headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : ''; + $headers['PHP_AUTH_PW'] = $this->parameters['PHP_AUTH_PW'] ?? ''; } else { /* * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default @@ -66,7 +64,7 @@ public function getHeaders() // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2); if (2 == \count($exploded)) { - list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded; + [$headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']] = $exploded; } } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) { // In some circumstances PHP_AUTH_DIGEST needs to be set @@ -89,7 +87,7 @@ public function getHeaders() // PHP_AUTH_USER/PHP_AUTH_PW if (isset($headers['PHP_AUTH_USER'])) { - $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']); + $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.($headers['PHP_AUTH_PW'] ?? '')); } elseif (isset($headers['PHP_AUTH_DIGEST'])) { $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST']; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBag.php index aad6b610e..11b884a71 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBag.php @@ -13,11 +13,13 @@ /** * This class relates to session attribute storage. + * + * @implements \IteratorAggregate */ class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable { - private $name = 'attributes'; - private $storageKey; + private string $name = 'attributes'; + private string $storageKey; protected $attributes = []; @@ -32,7 +34,7 @@ public function __construct(string $storageKey = '_sf2_attributes') /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->name; } @@ -53,7 +55,7 @@ public function initialize(array &$attributes) /** * {@inheritdoc} */ - public function getStorageKey() + public function getStorageKey(): string { return $this->storageKey; } @@ -61,7 +63,7 @@ public function getStorageKey() /** * {@inheritdoc} */ - public function has(string $name) + public function has(string $name): bool { return \array_key_exists($name, $this->attributes); } @@ -69,7 +71,7 @@ public function has(string $name) /** * {@inheritdoc} */ - public function get(string $name, $default = null) + public function get(string $name, mixed $default = null): mixed { return \array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; } @@ -77,7 +79,7 @@ public function get(string $name, $default = null) /** * {@inheritdoc} */ - public function set(string $name, $value) + public function set(string $name, mixed $value) { $this->attributes[$name] = $value; } @@ -85,7 +87,7 @@ public function set(string $name, $value) /** * {@inheritdoc} */ - public function all() + public function all(): array { return $this->attributes; } @@ -104,7 +106,7 @@ public function replace(array $attributes) /** * {@inheritdoc} */ - public function remove(string $name) + public function remove(string $name): mixed { $retval = null; if (\array_key_exists($name, $this->attributes)) { @@ -118,7 +120,7 @@ public function remove(string $name) /** * {@inheritdoc} */ - public function clear() + public function clear(): mixed { $return = $this->attributes; $this->attributes = []; @@ -129,19 +131,17 @@ public function clear() /** * Returns an iterator for attributes. * - * @return \ArrayIterator An \ArrayIterator instance + * @return \ArrayIterator */ - public function getIterator() + public function getIterator(): \ArrayIterator { return new \ArrayIterator($this->attributes); } /** * Returns the number of attributes. - * - * @return int The number of attributes */ - public function count() + public function count(): int { return \count($this->attributes); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php index 7017b717e..31a946444 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php @@ -22,33 +22,25 @@ interface AttributeBagInterface extends SessionBagInterface { /** * Checks if an attribute is defined. - * - * @return bool true if the attribute is defined, false otherwise */ - public function has(string $name); + public function has(string $name): bool; /** * Returns an attribute. - * - * @param mixed $default The default value if not found - * - * @return mixed */ - public function get(string $name, $default = null); + public function get(string $name, mixed $default = null): mixed; /** * Sets an attribute. - * - * @param mixed $value */ - public function set(string $name, $value); + public function set(string $name, mixed $value); /** * Returns attributes. * - * @return array + * @return array */ - public function all(); + public function all(): array; public function replace(array $attributes); @@ -57,5 +49,5 @@ public function replace(array $attributes); * * @return mixed The removed value or null when it does not exist */ - public function remove(string $name); + public function remove(string $name): mixed; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php deleted file mode 100644 index 7e752ddaa..000000000 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php +++ /dev/null @@ -1,157 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpFoundation\Session\Attribute; - -/** - * This class provides structured storage of session attributes using - * a name spacing character in the key. - * - * @author Drak - */ -class NamespacedAttributeBag extends AttributeBag -{ - private $namespaceCharacter; - - /** - * @param string $storageKey Session storage key - * @param string $namespaceCharacter Namespace character to use in keys - */ - public function __construct(string $storageKey = '_sf2_attributes', string $namespaceCharacter = '/') - { - $this->namespaceCharacter = $namespaceCharacter; - parent::__construct($storageKey); - } - - /** - * {@inheritdoc} - */ - public function has(string $name) - { - // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is - $attributes = $this->resolveAttributePath($name); - $name = $this->resolveKey($name); - - if (null === $attributes) { - return false; - } - - return \array_key_exists($name, $attributes); - } - - /** - * {@inheritdoc} - */ - public function get(string $name, $default = null) - { - // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is - $attributes = $this->resolveAttributePath($name); - $name = $this->resolveKey($name); - - if (null === $attributes) { - return $default; - } - - return \array_key_exists($name, $attributes) ? $attributes[$name] : $default; - } - - /** - * {@inheritdoc} - */ - public function set(string $name, $value) - { - $attributes = &$this->resolveAttributePath($name, true); - $name = $this->resolveKey($name); - $attributes[$name] = $value; - } - - /** - * {@inheritdoc} - */ - public function remove(string $name) - { - $retval = null; - $attributes = &$this->resolveAttributePath($name); - $name = $this->resolveKey($name); - if (null !== $attributes && \array_key_exists($name, $attributes)) { - $retval = $attributes[$name]; - unset($attributes[$name]); - } - - return $retval; - } - - /** - * Resolves a path in attributes property and returns it as a reference. - * - * This method allows structured namespacing of session attributes. - * - * @param string $name Key name - * @param bool $writeContext Write context, default false - * - * @return array|null - */ - protected function &resolveAttributePath(string $name, bool $writeContext = false) - { - $array = &$this->attributes; - $name = (0 === strpos($name, $this->namespaceCharacter)) ? substr($name, 1) : $name; - - // Check if there is anything to do, else return - if (!$name) { - return $array; - } - - $parts = explode($this->namespaceCharacter, $name); - if (\count($parts) < 2) { - if (!$writeContext) { - return $array; - } - - $array[$parts[0]] = []; - - return $array; - } - - unset($parts[\count($parts) - 1]); - - foreach ($parts as $part) { - if (null !== $array && !\array_key_exists($part, $array)) { - if (!$writeContext) { - $null = null; - - return $null; - } - - $array[$part] = []; - } - - $array = &$array[$part]; - } - - return $array; - } - - /** - * Resolves the key from the name. - * - * This is the last part in a dot separated string. - * - * @return string - */ - protected function resolveKey(string $name) - { - if (false !== $pos = strrpos($name, $this->namespaceCharacter)) { - $name = substr($name, $pos + 1); - } - - return $name; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php index 2707d64ec..9fea24f91 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php @@ -18,9 +18,9 @@ */ class AutoExpireFlashBag implements FlashBagInterface { - private $name = 'flashes'; - private $flashes = ['display' => [], 'new' => []]; - private $storageKey; + private string $name = 'flashes'; + private array $flashes = ['display' => [], 'new' => []]; + private string $storageKey; /** * @param string $storageKey The key used to store flashes in the session @@ -33,7 +33,7 @@ public function __construct(string $storageKey = '_symfony_flashes') /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->name; } @@ -60,7 +60,7 @@ public function initialize(array &$flashes) /** * {@inheritdoc} */ - public function add(string $type, $message) + public function add(string $type, mixed $message) { $this->flashes['new'][$type][] = $message; } @@ -68,7 +68,7 @@ public function add(string $type, $message) /** * {@inheritdoc} */ - public function peek(string $type, array $default = []) + public function peek(string $type, array $default = []): array { return $this->has($type) ? $this->flashes['display'][$type] : $default; } @@ -76,15 +76,15 @@ public function peek(string $type, array $default = []) /** * {@inheritdoc} */ - public function peekAll() + public function peekAll(): array { - return \array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : []; + return \array_key_exists('display', $this->flashes) ? $this->flashes['display'] : []; } /** * {@inheritdoc} */ - public function get(string $type, array $default = []) + public function get(string $type, array $default = []): array { $return = $default; @@ -103,7 +103,7 @@ public function get(string $type, array $default = []) /** * {@inheritdoc} */ - public function all() + public function all(): array { $return = $this->flashes['display']; $this->flashes['display'] = []; @@ -122,7 +122,7 @@ public function setAll(array $messages) /** * {@inheritdoc} */ - public function set(string $type, $messages) + public function set(string $type, string|array $messages) { $this->flashes['new'][$type] = (array) $messages; } @@ -130,7 +130,7 @@ public function set(string $type, $messages) /** * {@inheritdoc} */ - public function has(string $type) + public function has(string $type): bool { return \array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type]; } @@ -138,7 +138,7 @@ public function has(string $type) /** * {@inheritdoc} */ - public function keys() + public function keys(): array { return array_keys($this->flashes['display']); } @@ -146,7 +146,7 @@ public function keys() /** * {@inheritdoc} */ - public function getStorageKey() + public function getStorageKey(): string { return $this->storageKey; } @@ -154,7 +154,7 @@ public function getStorageKey() /** * {@inheritdoc} */ - public function clear() + public function clear(): mixed { return $this->all(); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBag.php index 88df7508a..4fa4644df 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBag.php @@ -18,9 +18,9 @@ */ class FlashBag implements FlashBagInterface { - private $name = 'flashes'; - private $flashes = []; - private $storageKey; + private string $name = 'flashes'; + private array $flashes = []; + private string $storageKey; /** * @param string $storageKey The key used to store flashes in the session @@ -33,7 +33,7 @@ public function __construct(string $storageKey = '_symfony_flashes') /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->name; } @@ -54,7 +54,7 @@ public function initialize(array &$flashes) /** * {@inheritdoc} */ - public function add(string $type, $message) + public function add(string $type, mixed $message) { $this->flashes[$type][] = $message; } @@ -62,7 +62,7 @@ public function add(string $type, $message) /** * {@inheritdoc} */ - public function peek(string $type, array $default = []) + public function peek(string $type, array $default = []): array { return $this->has($type) ? $this->flashes[$type] : $default; } @@ -70,7 +70,7 @@ public function peek(string $type, array $default = []) /** * {@inheritdoc} */ - public function peekAll() + public function peekAll(): array { return $this->flashes; } @@ -78,7 +78,7 @@ public function peekAll() /** * {@inheritdoc} */ - public function get(string $type, array $default = []) + public function get(string $type, array $default = []): array { if (!$this->has($type)) { return $default; @@ -94,7 +94,7 @@ public function get(string $type, array $default = []) /** * {@inheritdoc} */ - public function all() + public function all(): array { $return = $this->peekAll(); $this->flashes = []; @@ -105,7 +105,7 @@ public function all() /** * {@inheritdoc} */ - public function set(string $type, $messages) + public function set(string $type, string|array $messages) { $this->flashes[$type] = (array) $messages; } @@ -121,7 +121,7 @@ public function setAll(array $messages) /** * {@inheritdoc} */ - public function has(string $type) + public function has(string $type): bool { return \array_key_exists($type, $this->flashes) && $this->flashes[$type]; } @@ -129,7 +129,7 @@ public function has(string $type) /** * {@inheritdoc} */ - public function keys() + public function keys(): array { return array_keys($this->flashes); } @@ -137,7 +137,7 @@ public function keys() /** * {@inheritdoc} */ - public function getStorageKey() + public function getStorageKey(): string { return $this->storageKey; } @@ -145,7 +145,7 @@ public function getStorageKey() /** * {@inheritdoc} */ - public function clear() + public function clear(): mixed { return $this->all(); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBagInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBagInterface.php index 8713e71d0..cd10a23f3 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBagInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Flash/FlashBagInterface.php @@ -22,50 +22,38 @@ interface FlashBagInterface extends SessionBagInterface { /** * Adds a flash message for the given type. - * - * @param mixed $message */ - public function add(string $type, $message); + public function add(string $type, mixed $message); /** * Registers one or more messages for a given type. - * - * @param string|array $messages */ - public function set(string $type, $messages); + public function set(string $type, string|array $messages); /** * Gets flash messages for a given type. * * @param string $type Message category type * @param array $default Default value if $type does not exist - * - * @return array */ - public function peek(string $type, array $default = []); + public function peek(string $type, array $default = []): array; /** * Gets all flash messages. - * - * @return array */ - public function peekAll(); + public function peekAll(): array; /** * Gets and clears flash from the stack. * * @param array $default Default value if $type does not exist - * - * @return array */ - public function get(string $type, array $default = []); + public function get(string $type, array $default = []): array; /** * Gets and clears flashes from the stack. - * - * @return array */ - public function all(); + public function all(): array; /** * Sets all flash messages. @@ -74,15 +62,11 @@ public function setAll(array $messages); /** * Has flash messages for a given type? - * - * @return bool */ - public function has(string $type); + public function has(string $type): bool; /** * Returns a list of all defined types. - * - * @return array */ - public function keys(); + public function keys(): array; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Session.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Session.php index 8b02d2d0d..3254f1885 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Session.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Session.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; +use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; @@ -26,25 +27,29 @@ class_exists(SessionBagProxy::class); /** * @author Fabien Potencier * @author Drak + * + * @implements \IteratorAggregate */ class Session implements SessionInterface, \IteratorAggregate, \Countable { protected $storage; - private $flashName; - private $attributeName; - private $data = []; - private $usageIndex = 0; + private string $flashName; + private string $attributeName; + private array $data = []; + private int $usageIndex = 0; + private ?\Closure $usageReporter; - public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null) + public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null, callable $usageReporter = null) { - $this->storage = $storage ?: new NativeSessionStorage(); + $this->storage = $storage ?? new NativeSessionStorage(); + $this->usageReporter = $usageReporter instanceof \Closure || !\is_callable($usageReporter) ? $usageReporter : \Closure::fromCallable($usageReporter); - $attributes = $attributes ?: new AttributeBag(); + $attributes = $attributes ?? new AttributeBag(); $this->attributeName = $attributes->getName(); $this->registerBag($attributes); - $flashes = $flashes ?: new FlashBag(); + $flashes = $flashes ?? new FlashBag(); $this->flashName = $flashes->getName(); $this->registerBag($flashes); } @@ -52,7 +57,7 @@ public function __construct(SessionStorageInterface $storage = null, AttributeBa /** * {@inheritdoc} */ - public function start() + public function start(): bool { return $this->storage->start(); } @@ -60,7 +65,7 @@ public function start() /** * {@inheritdoc} */ - public function has(string $name) + public function has(string $name): bool { return $this->getAttributeBag()->has($name); } @@ -68,7 +73,7 @@ public function has(string $name) /** * {@inheritdoc} */ - public function get(string $name, $default = null) + public function get(string $name, mixed $default = null): mixed { return $this->getAttributeBag()->get($name, $default); } @@ -76,7 +81,7 @@ public function get(string $name, $default = null) /** * {@inheritdoc} */ - public function set(string $name, $value) + public function set(string $name, mixed $value) { $this->getAttributeBag()->set($name, $value); } @@ -84,7 +89,7 @@ public function set(string $name, $value) /** * {@inheritdoc} */ - public function all() + public function all(): array { return $this->getAttributeBag()->all(); } @@ -100,7 +105,7 @@ public function replace(array $attributes) /** * {@inheritdoc} */ - public function remove(string $name) + public function remove(string $name): mixed { return $this->getAttributeBag()->remove($name); } @@ -116,7 +121,7 @@ public function clear() /** * {@inheritdoc} */ - public function isStarted() + public function isStarted(): bool { return $this->storage->isStarted(); } @@ -124,19 +129,17 @@ public function isStarted() /** * Returns an iterator for attributes. * - * @return \ArrayIterator An \ArrayIterator instance + * @return \ArrayIterator */ - public function getIterator() + public function getIterator(): \ArrayIterator { return new \ArrayIterator($this->getAttributeBag()->all()); } /** * Returns the number of attributes. - * - * @return int */ - public function count() + public function count(): int { return \count($this->getAttributeBag()->all()); } @@ -153,6 +156,9 @@ public function isEmpty(): bool { if ($this->isStarted()) { ++$this->usageIndex; + if ($this->usageReporter && 0 <= $this->usageIndex) { + ($this->usageReporter)(); + } } foreach ($this->data as &$data) { if (!empty($data)) { @@ -166,7 +172,7 @@ public function isEmpty(): bool /** * {@inheritdoc} */ - public function invalidate(int $lifetime = null) + public function invalidate(int $lifetime = null): bool { $this->storage->clear(); @@ -176,7 +182,7 @@ public function invalidate(int $lifetime = null) /** * {@inheritdoc} */ - public function migrate(bool $destroy = false, int $lifetime = null) + public function migrate(bool $destroy = false, int $lifetime = null): bool { return $this->storage->regenerate($destroy, $lifetime); } @@ -192,7 +198,7 @@ public function save() /** * {@inheritdoc} */ - public function getId() + public function getId(): string { return $this->storage->getId(); } @@ -210,7 +216,7 @@ public function setId(string $id) /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->storage->getName(); } @@ -226,9 +232,12 @@ public function setName(string $name) /** * {@inheritdoc} */ - public function getMetadataBag() + public function getMetadataBag(): MetadataBag { ++$this->usageIndex; + if ($this->usageReporter && 0 <= $this->usageIndex) { + ($this->usageReporter)(); + } return $this->storage->getMetadataBag(); } @@ -238,13 +247,13 @@ public function getMetadataBag() */ public function registerBag(SessionBagInterface $bag) { - $this->storage->registerBag(new SessionBagProxy($bag, $this->data, $this->usageIndex)); + $this->storage->registerBag(new SessionBagProxy($bag, $this->data, $this->usageIndex, $this->usageReporter)); } /** * {@inheritdoc} */ - public function getBag(string $name) + public function getBag(string $name): SessionBagInterface { $bag = $this->storage->getBag($name); @@ -253,10 +262,8 @@ public function getBag(string $name) /** * Gets the flashbag interface. - * - * @return FlashBagInterface */ - public function getFlashBag() + public function getFlashBag(): FlashBagInterface { return $this->getBag($this->flashName); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagInterface.php index 8e37d06d6..821645d9b 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagInterface.php @@ -20,10 +20,8 @@ interface SessionBagInterface { /** * Gets this bag's name. - * - * @return string */ - public function getName(); + public function getName(): string; /** * Initializes the Bag. @@ -32,15 +30,13 @@ public function initialize(array &$array); /** * Gets the storage key for this bag. - * - * @return string */ - public function getStorageKey(); + public function getStorageKey(): string; /** * Clears out data from bag. * * @return mixed Whatever data was contained */ - public function clear(); + public function clear(): mixed; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagProxy.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagProxy.php index 0ae8231ef..1d405e3c7 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagProxy.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionBagProxy.php @@ -19,19 +19,24 @@ final class SessionBagProxy implements SessionBagInterface { private $bag; - private $data; - private $usageIndex; + private array $data; + private ?int $usageIndex; + private ?\Closure $usageReporter; - public function __construct(SessionBagInterface $bag, array &$data, ?int &$usageIndex) + public function __construct(SessionBagInterface $bag, array &$data, ?int &$usageIndex, ?callable $usageReporter) { $this->bag = $bag; $this->data = &$data; $this->usageIndex = &$usageIndex; + $this->usageReporter = $usageReporter instanceof \Closure || !\is_callable($usageReporter) ? $usageReporter : \Closure::fromCallable($usageReporter); } public function getBag(): SessionBagInterface { ++$this->usageIndex; + if ($this->usageReporter && 0 <= $this->usageIndex) { + ($this->usageReporter)(); + } return $this->bag; } @@ -42,6 +47,9 @@ public function isEmpty(): bool return true; } ++$this->usageIndex; + if ($this->usageReporter && 0 <= $this->usageIndex) { + ($this->usageReporter)(); + } return empty($this->data[$this->bag->getStorageKey()]); } @@ -60,6 +68,10 @@ public function getName(): string public function initialize(array &$array): void { ++$this->usageIndex; + if ($this->usageReporter && 0 <= $this->usageIndex) { + ($this->usageReporter)(); + } + $this->data[$this->bag->getStorageKey()] = &$array; $this->bag->initialize($array); @@ -76,7 +88,7 @@ public function getStorageKey(): string /** * {@inheritdoc} */ - public function clear() + public function clear(): mixed { return $this->bag->clear(); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactory.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactory.php new file mode 100644 index 000000000..ffbd82cc4 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactory.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\HttpFoundation\Session; + +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageFactoryInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(Session::class); + +/** + * @author Jérémy Derussé + */ +class SessionFactory implements SessionFactoryInterface +{ + private $requestStack; + private $storageFactory; + private ?\Closure $usageReporter; + + public function __construct(RequestStack $requestStack, SessionStorageFactoryInterface $storageFactory, callable $usageReporter = null) + { + $this->requestStack = $requestStack; + $this->storageFactory = $storageFactory; + $this->usageReporter = $usageReporter instanceof \Closure || !\is_callable($usageReporter) ? $usageReporter : \Closure::fromCallable($usageReporter); + } + + public function createSession(): SessionInterface + { + return new Session($this->storageFactory->createStorage($this->requestStack->getMainRequest()), null, null, $this->usageReporter); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/mime/BodyRendererInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactoryInterface.php similarity index 57% rename from lam/lib/3rdParty/composer/symfony/mime/BodyRendererInterface.php rename to lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactoryInterface.php index d69217265..b24fdc495 100644 --- a/lam/lib/3rdParty/composer/symfony/mime/BodyRendererInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionFactoryInterface.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Mime; +namespace Symfony\Component\HttpFoundation\Session; /** - * @author Fabien Potencier + * @author Kevin Bond */ -interface BodyRendererInterface +interface SessionFactoryInterface { - public function render(Message $message): void; + public function createSession(): SessionInterface; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionInterface.php index b2f09fd0d..ae0c9b7d3 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/SessionInterface.php @@ -23,18 +23,14 @@ interface SessionInterface /** * Starts the session storage. * - * @return bool - * * @throws \RuntimeException if session fails to start */ - public function start(); + public function start(): bool; /** * Returns the session ID. - * - * @return string */ - public function getId(); + public function getId(): string; /** * Sets the session ID. @@ -43,10 +39,8 @@ public function setId(string $id); /** * Returns the session name. - * - * @return string */ - public function getName(); + public function getName(): string; /** * Sets the session name. @@ -63,10 +57,8 @@ public function setName(string $name); * will leave the system settings unchanged, 0 sets the cookie * to expire with browser session. Time is in seconds, and is * not a Unix timestamp. - * - * @return bool */ - public function invalidate(int $lifetime = null); + public function invalidate(int $lifetime = null): bool; /** * Migrates the current session to a new session id while maintaining all @@ -77,10 +69,8 @@ public function invalidate(int $lifetime = null); * will leave the system settings unchanged, 0 sets the cookie * to expire with browser session. Time is in seconds, and is * not a Unix timestamp. - * - * @return bool */ - public function migrate(bool $destroy = false, int $lifetime = null); + public function migrate(bool $destroy = false, int $lifetime = null): bool; /** * Force the session to be saved and closed. @@ -93,33 +83,23 @@ public function save(); /** * Checks if an attribute is defined. - * - * @return bool */ - public function has(string $name); + public function has(string $name): bool; /** * Returns an attribute. - * - * @param mixed $default The default value if not found - * - * @return mixed */ - public function get(string $name, $default = null); + public function get(string $name, mixed $default = null): mixed; /** * Sets an attribute. - * - * @param mixed $value */ - public function set(string $name, $value); + public function set(string $name, mixed $value); /** * Returns attributes. - * - * @return array */ - public function all(); + public function all(): array; /** * Sets attributes. @@ -131,7 +111,7 @@ public function replace(array $attributes); * * @return mixed The removed value or null when it does not exist */ - public function remove(string $name); + public function remove(string $name): mixed; /** * Clears all attributes. @@ -140,10 +120,8 @@ public function clear(); /** * Checks if the session was started. - * - * @return bool */ - public function isStarted(); + public function isStarted(): bool; /** * Registers a SessionBagInterface with the session. @@ -152,15 +130,11 @@ public function registerBag(SessionBagInterface $bag); /** * Gets a bag instance by name. - * - * @return SessionBagInterface */ - public function getBag(string $name); + public function getBag(string $name): SessionBagInterface; /** * Gets session meta. - * - * @return MetadataBag */ - public function getMetadataBag(); + public function getMetadataBag(): MetadataBag; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php index bd151669c..cfaa6c81a 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php @@ -22,44 +22,29 @@ */ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface { - private $sessionName; - private $prefetchId; - private $prefetchData; - private $newSessionId; - private $igbinaryEmptyData; - - /** - * @return bool - */ - public function open($savePath, $sessionName) + private string $sessionName; + private string $prefetchId; + private string $prefetchData; + private ?string $newSessionId = null; + private string $igbinaryEmptyData; + + public function open(string $savePath, string $sessionName): bool { $this->sessionName = $sessionName; - if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) { - header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire'))); + if (!headers_sent() && !\ini_get('session.cache_limiter') && '0' !== \ini_get('session.cache_limiter')) { + header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) \ini_get('session.cache_expire'))); } return true; } - /** - * @return string - */ - abstract protected function doRead(string $sessionId); - - /** - * @return bool - */ - abstract protected function doWrite(string $sessionId, string $data); - - /** - * @return bool - */ - abstract protected function doDestroy(string $sessionId); - - /** - * @return bool - */ - public function validateId($sessionId) + abstract protected function doRead(string $sessionId): string; + + abstract protected function doWrite(string $sessionId, string $data): bool; + + abstract protected function doDestroy(string $sessionId): bool; + + public function validateId(string $sessionId): bool { $this->prefetchData = $this->read($sessionId); $this->prefetchId = $sessionId; @@ -67,15 +52,12 @@ public function validateId($sessionId) return '' !== $this->prefetchData; } - /** - * @return string - */ - public function read($sessionId) + public function read(string $sessionId): string { - if (null !== $this->prefetchId) { + if (isset($this->prefetchId)) { $prefetchId = $this->prefetchId; $prefetchData = $this->prefetchData; - $this->prefetchId = $this->prefetchData = null; + unset($this->prefetchId, $this->prefetchData); if ($prefetchId === $sessionId || '' === $prefetchData) { $this->newSessionId = '' === $prefetchData ? $sessionId : null; @@ -90,15 +72,10 @@ public function read($sessionId) return $data; } - /** - * @return bool - */ - public function write($sessionId, $data) + public function write(string $sessionId, string $data): bool { - if (null === $this->igbinaryEmptyData) { - // see https://github.com/igbinary/igbinary/issues/146 - $this->igbinaryEmptyData = \function_exists('igbinary_serialize') ? igbinary_serialize([]) : ''; - } + // see https://github.com/igbinary/igbinary/issues/146 + $this->igbinaryEmptyData ??= \function_exists('igbinary_serialize') ? igbinary_serialize([]) : ''; if ('' === $data || $this->igbinaryEmptyData === $data) { return $this->destroy($sessionId); } @@ -107,13 +84,10 @@ public function write($sessionId, $data) return $this->doWrite($sessionId, $data); } - /** - * @return bool - */ - public function destroy($sessionId) + public function destroy(string $sessionId): bool { - if (!headers_sent() && filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN)) { - if (!$this->sessionName) { + if (!headers_sent() && filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) { + if (!isset($this->sessionName)) { throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', static::class)); } $cookie = SessionUtils::popSessionCookie($this->sessionName, $sessionId); @@ -126,13 +100,9 @@ public function destroy($sessionId) * started the session). */ if (null === $cookie || isset($_COOKIE[$this->sessionName])) { - if (\PHP_VERSION_ID < 70300) { - setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN), filter_var(ini_get('session.cookie_httponly'), FILTER_VALIDATE_BOOLEAN)); - } else { - $params = session_get_cookie_params(); - unset($params['lifetime']); - setcookie($this->sessionName, '', $params); - } + $params = session_get_cookie_params(); + unset($params['lifetime']); + setcookie($this->sessionName, '', $params); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/IdentityMarshaller.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/IdentityMarshaller.php new file mode 100644 index 000000000..bea3a323e --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/IdentityMarshaller.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +use Symfony\Component\Cache\Marshaller\MarshallerInterface; + +/** + * @author Ahmed TAILOULOUTE + */ +class IdentityMarshaller implements MarshallerInterface +{ + /** + * {@inheritdoc} + */ + public function marshall(array $values, ?array &$failed): array + { + foreach ($values as $key => $value) { + if (!\is_string($value)) { + throw new \LogicException(sprintf('%s accepts only string as data.', __METHOD__)); + } + } + + return $values; + } + + /** + * {@inheritdoc} + */ + public function unmarshall(string $value): string + { + return $value; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php new file mode 100644 index 000000000..377d1e090 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.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\HttpFoundation\Session\Storage\Handler; + +use Symfony\Component\Cache\Marshaller\MarshallerInterface; + +/** + * @author Ahmed TAILOULOUTE + */ +class MarshallingSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface +{ + private $handler; + private $marshaller; + + public function __construct(AbstractSessionHandler $handler, MarshallerInterface $marshaller) + { + $this->handler = $handler; + $this->marshaller = $marshaller; + } + + public function open(string $savePath, string $name): bool + { + return $this->handler->open($savePath, $name); + } + + public function close(): bool + { + return $this->handler->close(); + } + + public function destroy(string $sessionId): bool + { + return $this->handler->destroy($sessionId); + } + + public function gc(int $maxlifetime): int|false + { + return $this->handler->gc($maxlifetime); + } + + public function read(string $sessionId): string + { + return $this->marshaller->unmarshall($this->handler->read($sessionId)); + } + + public function write(string $sessionId, string $data): bool + { + $failed = []; + $marshalledData = $this->marshaller->marshall(['data' => $data], $failed); + + if (isset($failed['data'])) { + return false; + } + + return $this->handler->write($sessionId, $marshalledData['data']); + } + + public function validateId(string $sessionId): bool + { + return $this->handler->validateId($sessionId); + } + + public function updateTimestamp(string $sessionId, string $data): bool + { + return $this->handler->updateTimestamp($sessionId, $data); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php index 828d29eb5..b61a6d0e9 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php @@ -24,21 +24,21 @@ class MemcachedSessionHandler extends AbstractSessionHandler private $memcached; /** - * @var int Time to live in seconds + * Time to live in seconds. */ - private $ttl; + private ?int $ttl; /** - * @var string Key prefix for shared environments + * Key prefix for shared environments. */ - private $prefix; + private string $prefix; /** * Constructor. * * List of available options: * * prefix: The prefix to use for the memcached keys in order to avoid collision - * * expiretime: The time to live in seconds. + * * ttl: The time to live in seconds. * * @throws \InvalidArgumentException When unsupported options are passed */ @@ -46,18 +46,15 @@ public function __construct(\Memcached $memcached, array $options = []) { $this->memcached = $memcached; - if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime'])) { + if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime', 'ttl'])) { throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff))); } - $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400; - $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s'; + $this->ttl = $options['expiretime'] ?? $options['ttl'] ?? null; + $this->prefix = $options['prefix'] ?? 'sf2s'; } - /** - * @return bool - */ - public function close() + public function close(): bool { return $this->memcached->quit(); } @@ -65,17 +62,14 @@ public function close() /** * {@inheritdoc} */ - protected function doRead(string $sessionId) + protected function doRead(string $sessionId): string { return $this->memcached->get($this->prefix.$sessionId) ?: ''; } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { - $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl); + $this->memcached->touch($this->prefix.$sessionId, $this->getCompatibleTtl()); return true; } @@ -83,36 +77,44 @@ public function updateTimestamp($sessionId, $data) /** * {@inheritdoc} */ - protected function doWrite(string $sessionId, string $data) + protected function doWrite(string $sessionId, string $data): bool + { + return $this->memcached->set($this->prefix.$sessionId, $data, $this->getCompatibleTtl()); + } + + private function getCompatibleTtl(): int { - return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl); + $ttl = (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')); + + // If the relative TTL that is used exceeds 30 days, memcached will treat the value as Unix time. + // We have to convert it to an absolute Unix time at this point, to make sure the TTL is correct. + if ($ttl > 60 * 60 * 24 * 30) { + $ttl += time(); + } + + return $ttl; } /** * {@inheritdoc} */ - protected function doDestroy(string $sessionId) + protected function doDestroy(string $sessionId): bool { $result = $this->memcached->delete($this->prefix.$sessionId); return $result || \Memcached::RES_NOTFOUND == $this->memcached->getResultCode(); } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { // not required here because memcached will auto expire the records anyhow. - return true; + return 0; } /** * Return a Memcached instance. - * - * @return \Memcached */ - protected function getMemcached() + protected function getMemcached(): \Memcached { return $this->memcached; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php index c6b16d11c..1d4255236 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php @@ -22,8 +22,15 @@ */ class MigratingSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface { - private $currentHandler; - private $writeOnlyHandler; + /** + * @var \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface + */ + private \SessionHandlerInterface $currentHandler; + + /** + * @var \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface + */ + private \SessionHandlerInterface $writeOnlyHandler; public function __construct(\SessionHandlerInterface $currentHandler, \SessionHandlerInterface $writeOnlyHandler) { @@ -38,10 +45,7 @@ public function __construct(\SessionHandlerInterface $currentHandler, \SessionHa $this->writeOnlyHandler = $writeOnlyHandler; } - /** - * @return bool - */ - public function close() + public function close(): bool { $result = $this->currentHandler->close(); $this->writeOnlyHandler->close(); @@ -49,10 +53,7 @@ public function close() return $result; } - /** - * @return bool - */ - public function destroy($sessionId) + public function destroy(string $sessionId): bool { $result = $this->currentHandler->destroy($sessionId); $this->writeOnlyHandler->destroy($sessionId); @@ -60,10 +61,7 @@ public function destroy($sessionId) return $result; } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { $result = $this->currentHandler->gc($maxlifetime); $this->writeOnlyHandler->gc($maxlifetime); @@ -71,10 +69,7 @@ public function gc($maxlifetime) return $result; } - /** - * @return bool - */ - public function open($savePath, $sessionName) + public function open(string $savePath, string $sessionName): bool { $result = $this->currentHandler->open($savePath, $sessionName); $this->writeOnlyHandler->open($savePath, $sessionName); @@ -82,19 +77,13 @@ public function open($savePath, $sessionName) return $result; } - /** - * @return string - */ - public function read($sessionId) + public function read(string $sessionId): string { // No reading from new handler until switch-over return $this->currentHandler->read($sessionId); } - /** - * @return bool - */ - public function write($sessionId, $sessionData) + public function write(string $sessionId, string $sessionData): bool { $result = $this->currentHandler->write($sessionId, $sessionData); $this->writeOnlyHandler->write($sessionId, $sessionData); @@ -102,19 +91,13 @@ public function write($sessionId, $sessionData) return $result; } - /** - * @return bool - */ - public function validateId($sessionId) + public function validateId(string $sessionId): bool { // No reading from new handler until switch-over return $this->currentHandler->validateId($sessionId); } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $sessionData) + public function updateTimestamp(string $sessionId, string $sessionData): bool { $result = $this->currentHandler->updateTimestamp($sessionId, $sessionData); $this->writeOnlyHandler->updateTimestamp($sessionId, $sessionData); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php index 9a2d7919a..f4886dd9c 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php @@ -11,6 +11,11 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; +use MongoDB\BSON\Binary; +use MongoDB\BSON\UTCDateTime; +use MongoDB\Client; +use MongoDB\Collection; + /** * Session handler using the mongodb/mongodb package and MongoDB driver extension. * @@ -22,16 +27,8 @@ class MongoDbSessionHandler extends AbstractSessionHandler { private $mongo; - - /** - * @var \MongoDB\Collection - */ private $collection; - - /** - * @var array - */ - private $options; + private array $options; /** * Constructor. @@ -51,7 +48,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions * automatically. Such an index can for example look like this: * - * db..ensureIndex( + * db..createIndex( * { "": 1 }, * { "expireAfterSeconds": 0 } * ) @@ -63,7 +60,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler * * @throws \InvalidArgumentException When "database" or "collection" not provided */ - public function __construct(\MongoDB\Client $mongo, array $options) + public function __construct(Client $mongo, array $options) { if (!isset($options['database']) || !isset($options['collection'])) { throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.'); @@ -79,10 +76,7 @@ public function __construct(\MongoDB\Client $mongo, array $options) ], $options); } - /** - * @return bool - */ - public function close() + public function close(): bool { return true; } @@ -90,7 +84,7 @@ public function close() /** * {@inheritdoc} */ - protected function doDestroy(string $sessionId) + protected function doDestroy(string $sessionId): bool { $this->getCollection()->deleteOne([ $this->options['id_field'] => $sessionId, @@ -99,29 +93,24 @@ protected function doDestroy(string $sessionId) return true; } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { - $this->getCollection()->deleteMany([ - $this->options['expiry_field'] => ['$lt' => new \MongoDB\BSON\UTCDateTime()], - ]); - - return true; + return $this->getCollection()->deleteMany([ + $this->options['expiry_field'] => ['$lt' => new UTCDateTime()], + ])->getDeletedCount(); } /** * {@inheritdoc} */ - protected function doWrite(string $sessionId, string $data) + protected function doWrite(string $sessionId, string $data): bool { - $expiry = new \MongoDB\BSON\UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000); + $expiry = new UTCDateTime((time() + (int) \ini_get('session.gc_maxlifetime')) * 1000); $fields = [ - $this->options['time_field'] => new \MongoDB\BSON\UTCDateTime(), + $this->options['time_field'] => new UTCDateTime(), $this->options['expiry_field'] => $expiry, - $this->options['data_field'] => new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY), + $this->options['data_field'] => new Binary($data, Binary::TYPE_OLD_BINARY), ]; $this->getCollection()->updateOne( @@ -133,17 +122,14 @@ protected function doWrite(string $sessionId, string $data) return true; } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { - $expiry = new \MongoDB\BSON\UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000); + $expiry = new UTCDateTime((time() + (int) \ini_get('session.gc_maxlifetime')) * 1000); $this->getCollection()->updateOne( [$this->options['id_field'] => $sessionId], ['$set' => [ - $this->options['time_field'] => new \MongoDB\BSON\UTCDateTime(), + $this->options['time_field'] => new UTCDateTime(), $this->options['expiry_field'] => $expiry, ]] ); @@ -154,11 +140,11 @@ public function updateTimestamp($sessionId, $data) /** * {@inheritdoc} */ - protected function doRead(string $sessionId) + protected function doRead(string $sessionId): string { $dbData = $this->getCollection()->findOne([ $this->options['id_field'] => $sessionId, - $this->options['expiry_field'] => ['$gte' => new \MongoDB\BSON\UTCDateTime()], + $this->options['expiry_field'] => ['$gte' => new UTCDateTime()], ]); if (null === $dbData) { @@ -168,19 +154,12 @@ protected function doRead(string $sessionId) return $dbData[$this->options['data_field']]->getData(); } - private function getCollection(): \MongoDB\Collection + private function getCollection(): Collection { - if (null === $this->collection) { - $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']); - } - - return $this->collection; + return $this->collection ??= $this->mongo->selectCollection($this->options['database'], $this->options['collection']); } - /** - * @return \MongoDB\Client - */ - protected function getMongo() + protected function getMongo(): Client { return $this->mongo; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php index effc9db54..1ca4bfeb0 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php @@ -31,7 +31,7 @@ class NativeFileSessionHandler extends \SessionHandler public function __construct(string $savePath = null) { if (null === $savePath) { - $savePath = ini_get('session.save_path'); + $savePath = \ini_get('session.save_path'); } $baseDir = $savePath; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php index aa0e595c6..fb2d363b6 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php @@ -18,18 +18,12 @@ */ class NullSessionHandler extends AbstractSessionHandler { - /** - * @return bool - */ - public function close() + public function close(): bool { return true; } - /** - * @return bool - */ - public function validateId($sessionId) + public function validateId(string $sessionId): bool { return true; } @@ -37,15 +31,12 @@ public function validateId($sessionId) /** * {@inheritdoc} */ - protected function doRead(string $sessionId) + protected function doRead(string $sessionId): string { return ''; } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { return true; } @@ -53,7 +44,7 @@ public function updateTimestamp($sessionId, $data) /** * {@inheritdoc} */ - protected function doWrite(string $sessionId, string $data) + protected function doWrite(string $sessionId, string $data): bool { return true; } @@ -61,16 +52,13 @@ protected function doWrite(string $sessionId, string $data) /** * {@inheritdoc} */ - protected function doDestroy(string $sessionId) + protected function doDestroy(string $sessionId): bool { return true; } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { - return true; + return 0; } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php index a301e9f05..40ac49d91 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php @@ -46,7 +46,7 @@ class PdoSessionHandler extends AbstractSessionHandler * write will win in this case. It might be useful when you implement your own * logic to deal with this like an optimistic approach. */ - const LOCK_NONE = 0; + public const LOCK_NONE = 0; /** * Creates an application-level lock on a session. The disadvantage is that the @@ -55,7 +55,7 @@ class PdoSessionHandler extends AbstractSessionHandler * does not require a transaction. * This mode is not available for SQLite and not yet implemented for oci and sqlsrv. */ - const LOCK_ADVISORY = 1; + public const LOCK_ADVISORY = 1; /** * Issues a real row lock. Since it uses a transaction between opening and @@ -63,91 +63,63 @@ class PdoSessionHandler extends AbstractSessionHandler * that you also use for your application logic. This mode is the default because * it's the only reliable solution across DBMSs. */ - const LOCK_TRANSACTIONAL = 2; + public const LOCK_TRANSACTIONAL = 2; - private const MAX_LIFETIME = 315576000; - - /** - * @var \PDO|null PDO instance or null when not connected yet - */ private $pdo; /** - * @var string|false|null DSN string or null for session.save_path or false when lazy connection disabled - */ - private $dsn = false; - - /** - * @var string Database driver - */ - private $driver; - - /** - * @var string Table name - */ - private $table = 'sessions'; - - /** - * @var string Column for session id + * DSN string or null for session.save_path or false when lazy connection disabled. */ - private $idCol = 'sess_id'; + private string|false|null $dsn = false; - /** - * @var string Column for session data - */ - private $dataCol = 'sess_data'; - - /** - * @var string Column for lifetime - */ - private $lifetimeCol = 'sess_lifetime'; - - /** - * @var string Column for timestamp - */ - private $timeCol = 'sess_time'; + private string $driver; + private string $table = 'sessions'; + private string $idCol = 'sess_id'; + private string $dataCol = 'sess_data'; + private string $lifetimeCol = 'sess_lifetime'; + private string $timeCol = 'sess_time'; /** - * @var string Username when lazy-connect + * Username when lazy-connect. */ - private $username = ''; + private string $username = ''; /** - * @var string Password when lazy-connect + * Password when lazy-connect. */ - private $password = ''; + private string $password = ''; /** - * @var array Connection options when lazy-connect + * Connection options when lazy-connect. */ - private $connectionOptions = []; + private array $connectionOptions = []; /** - * @var int The strategy for locking, see constants + * The strategy for locking, see constants. */ - private $lockMode = self::LOCK_TRANSACTIONAL; + private int $lockMode = self::LOCK_TRANSACTIONAL; /** * It's an array to support multiple reads before closing which is manual, non-standard usage. * * @var \PDOStatement[] An array of statements to release advisory locks */ - private $unlockStatements = []; + private array $unlockStatements = []; /** - * @var bool True when the current session exists but expired according to session.gc_maxlifetime + * True when the current session exists but expired according to session.gc_maxlifetime. */ - private $sessionExpired = false; + private bool $sessionExpired = false; /** - * @var bool Whether a transaction is active + * Whether a transaction is active. */ - private $inTransaction = false; + private bool $inTransaction = false; /** - * @var bool Whether gc() has been called + * Whether gc() has been called. */ - private $gcCalled = false; + private bool $gcCalled = false; /** * You can either pass an existing database connection as PDO instance or @@ -170,7 +142,7 @@ class PdoSessionHandler extends AbstractSessionHandler * * @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION */ - public function __construct($pdoOrDsn = null, array $options = []) + public function __construct(\PDO|string $pdoOrDsn = null, array $options = []) { if ($pdoOrDsn instanceof \PDO) { if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { @@ -179,21 +151,21 @@ public function __construct($pdoOrDsn = null, array $options = []) $this->pdo = $pdoOrDsn; $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); - } elseif (\is_string($pdoOrDsn) && false !== strpos($pdoOrDsn, '://')) { + } elseif (\is_string($pdoOrDsn) && str_contains($pdoOrDsn, '://')) { $this->dsn = $this->buildDsnFromUrl($pdoOrDsn); } else { $this->dsn = $pdoOrDsn; } - $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table; - $this->idCol = isset($options['db_id_col']) ? $options['db_id_col'] : $this->idCol; - $this->dataCol = isset($options['db_data_col']) ? $options['db_data_col'] : $this->dataCol; - $this->lifetimeCol = isset($options['db_lifetime_col']) ? $options['db_lifetime_col'] : $this->lifetimeCol; - $this->timeCol = isset($options['db_time_col']) ? $options['db_time_col'] : $this->timeCol; - $this->username = isset($options['db_username']) ? $options['db_username'] : $this->username; - $this->password = isset($options['db_password']) ? $options['db_password'] : $this->password; - $this->connectionOptions = isset($options['db_connection_options']) ? $options['db_connection_options'] : $this->connectionOptions; - $this->lockMode = isset($options['lock_mode']) ? $options['lock_mode'] : $this->lockMode; + $this->table = $options['db_table'] ?? $this->table; + $this->idCol = $options['db_id_col'] ?? $this->idCol; + $this->dataCol = $options['db_data_col'] ?? $this->dataCol; + $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol; + $this->timeCol = $options['db_time_col'] ?? $this->timeCol; + $this->username = $options['db_username'] ?? $this->username; + $this->password = $options['db_password'] ?? $this->password; + $this->connectionOptions = $options['db_connection_options'] ?? $this->connectionOptions; + $this->lockMode = $options['lock_mode'] ?? $this->lockMode; } /** @@ -251,32 +223,24 @@ public function createTable() * Returns true when the current session exists but expired according to session.gc_maxlifetime. * * Can be used to distinguish between a new session and one that expired due to inactivity. - * - * @return bool Whether current session expired */ - public function isSessionExpired() + public function isSessionExpired(): bool { return $this->sessionExpired; } - /** - * @return bool - */ - public function open($savePath, $sessionName) + public function open(string $savePath, string $sessionName): bool { $this->sessionExpired = false; - if (null === $this->pdo) { + if (!isset($this->pdo)) { $this->connect($this->dsn ?: $savePath); } return parent::open($savePath, $sessionName); } - /** - * @return string - */ - public function read($sessionId) + public function read(string $sessionId): string { try { return parent::read($sessionId); @@ -287,22 +251,19 @@ public function read($sessionId) } } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process. // This way, pruning expired sessions does not block them from being started while the current session is used. $this->gcCalled = true; - return true; + return 0; } /** * {@inheritdoc} */ - protected function doDestroy(string $sessionId) + protected function doDestroy(string $sessionId): bool { // delete the record associated with this id $sql = "DELETE FROM $this->table WHERE $this->idCol = :id"; @@ -323,9 +284,9 @@ protected function doDestroy(string $sessionId) /** * {@inheritdoc} */ - protected function doWrite(string $sessionId, string $data) + protected function doWrite(string $sessionId, string $data): bool { - $maxlifetime = (int) ini_get('session.gc_maxlifetime'); + $maxlifetime = (int) \ini_get('session.gc_maxlifetime'); try { // We use a single MERGE SQL query when supported by the database. @@ -350,7 +311,7 @@ protected function doWrite(string $sessionId, string $data) $insertStmt->execute(); } catch (\PDOException $e) { // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys - if (0 === strpos($e->getCode(), '23')) { + if (str_starts_with($e->getCode(), '23')) { $updateStmt->execute(); } else { throw $e; @@ -366,12 +327,9 @@ protected function doWrite(string $sessionId, string $data) return true; } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { - $expiry = time() + (int) ini_get('session.gc_maxlifetime'); + $expiry = time() + (int) \ini_get('session.gc_maxlifetime'); try { $updateStmt = $this->pdo->prepare( @@ -390,10 +348,7 @@ public function updateTimestamp($sessionId, $data) return true; } - /** - * @return bool - */ - public function close() + public function close(): bool { $this->commit(); @@ -405,26 +360,14 @@ public function close() $this->gcCalled = false; // delete the session records that have expired - $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time AND $this->lifetimeCol > :min"; + $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time"; $stmt = $this->pdo->prepare($sql); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); - $stmt->bindValue(':min', self::MAX_LIFETIME, \PDO::PARAM_INT); - $stmt->execute(); - // to be removed in 6.0 - if ('mysql' === $this->driver) { - $legacySql = "DELETE FROM $this->table WHERE $this->lifetimeCol <= :min AND $this->lifetimeCol + $this->timeCol < :time"; - } else { - $legacySql = "DELETE FROM $this->table WHERE $this->lifetimeCol <= :min AND $this->lifetimeCol < :time - $this->timeCol"; - } - - $stmt = $this->pdo->prepare($legacySql); - $stmt->bindValue(':time', time(), \PDO::PARAM_INT); - $stmt->bindValue(':min', self::MAX_LIFETIME, \PDO::PARAM_INT); $stmt->execute(); } if (false !== $this->dsn) { - $this->pdo = null; // only close lazy-connection + unset($this->pdo, $this->driver); // only close lazy-connection } return true; @@ -479,17 +422,39 @@ private function buildDsnFromUrl(string $dsnOrUrl): string 'sqlite3' => 'sqlite', ]; - $driver = isset($driverAliasMap[$params['scheme']]) ? $driverAliasMap[$params['scheme']] : $params['scheme']; + $driver = $driverAliasMap[$params['scheme']] ?? $params['scheme']; // Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here. - if (0 === strpos($driver, 'pdo_') || 0 === strpos($driver, 'pdo-')) { + if (str_starts_with($driver, 'pdo_') || str_starts_with($driver, 'pdo-')) { $driver = substr($driver, 4); } + $dsn = null; switch ($driver) { case 'mysql': + $dsn = 'mysql:'; + if ('' !== ($params['query'] ?? '')) { + $queryParams = []; + parse_str($params['query'], $queryParams); + if ('' !== ($queryParams['charset'] ?? '')) { + $dsn .= 'charset='.$queryParams['charset'].';'; + } + + if ('' !== ($queryParams['unix_socket'] ?? '')) { + $dsn .= 'unix_socket='.$queryParams['unix_socket'].';'; + + if (isset($params['path'])) { + $dbName = substr($params['path'], 1); // Remove the leading slash + $dsn .= 'dbname='.$dbName.';'; + } + + return $dsn; + } + } + // If "unix_socket" is not in the query, we continue with the same process as pgsql + // no break case 'pgsql': - $dsn = $driver.':'; + $dsn ?? $dsn = 'pgsql:'; if (isset($params['host']) && '' !== $params['host']) { $dsn .= 'host='.$params['host'].';'; @@ -605,10 +570,8 @@ private function rollback(): void * * We need to make sure we do not return session data that is already considered garbage according * to the session.gc_maxlifetime setting because gc() is called after read() and only sometimes. - * - * @return string */ - protected function doRead(string $sessionId) + protected function doRead(string $sessionId): string { if (self::LOCK_ADVISORY === $this->lockMode) { $this->unlockStatements[] = $this->doAdvisoryLock($sessionId); @@ -619,15 +582,12 @@ protected function doRead(string $sessionId) $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); $insertStmt = null; - do { + while (true) { $selectStmt->execute(); $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM); if ($sessionRows) { $expiry = (int) $sessionRows[0][1]; - if ($expiry <= self::MAX_LIFETIME) { - $expiry += $sessionRows[0][2]; - } if ($expiry < time()) { $this->sessionExpired = true; @@ -643,7 +603,7 @@ protected function doRead(string $sessionId) throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.'); } - if (!filter_var(ini_get('session.use_strict_mode'), FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { + if (!filter_var(\ini_get('session.use_strict_mode'), \FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { // In strict mode, session fixation is not possible: new sessions always start with a unique // random id, so that concurrency is not possible and this code path can be skipped. // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block @@ -654,7 +614,7 @@ protected function doRead(string $sessionId) } catch (\PDOException $e) { // Catch duplicate key error because other connection created the session already. // It would only not be the case when the other connection destroyed the session. - if (0 === strpos($e->getCode(), '23')) { + if (str_starts_with($e->getCode(), '23')) { // Retrieve finished session data written by concurrent connection by restarting the loop. // We have to start a new transaction as a failed query will mark the current transaction as // aborted in PostgreSQL and disallow further queries within it. @@ -668,7 +628,7 @@ protected function doRead(string $sessionId) } return ''; - } while (true); + } } /** @@ -760,14 +720,13 @@ private function getSelectSql(): string if (self::LOCK_TRANSACTIONAL === $this->lockMode) { $this->beginTransaction(); - // selecting the time column should be removed in 6.0 switch ($this->driver) { case 'mysql': case 'oci': case 'pgsql': - return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id FOR UPDATE"; + return "SELECT $this->dataCol, $this->lifetimeCol FROM $this->table WHERE $this->idCol = :id FOR UPDATE"; case 'sqlsrv': - return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WITH (UPDLOCK, ROWLOCK) WHERE $this->idCol = :id"; + return "SELECT $this->dataCol, $this->lifetimeCol FROM $this->table WITH (UPDLOCK, ROWLOCK) WHERE $this->idCol = :id"; case 'sqlite': // we already locked when starting transaction break; @@ -776,7 +735,7 @@ private function getSelectSql(): string } } - return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id"; + return "SELECT $this->dataCol, $this->lifetimeCol FROM $this->table WHERE $this->idCol = :id"; } /** @@ -885,13 +844,11 @@ private function getMergeStatement(string $sessionId, string $data, int $maxlife /** * Return a PDO instance. - * - * @return \PDO */ - protected function getConnection() + protected function getConnection(): \PDO { - if (null === $this->pdo) { - $this->connect($this->dsn ?: ini_get('session.save_path')); + if (!isset($this->pdo)) { + $this->connect($this->dsn ?: \ini_get('session.save_path')); } return $this->pdo; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php index d6c37c430..f9f3ce6ed 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php @@ -26,37 +26,24 @@ class RedisSessionHandler extends AbstractSessionHandler private $redis; /** - * @var string Key prefix for shared environments + * Key prefix for shared environments. */ - private $prefix; + private string $prefix; /** - * @var int Time to live in seconds + * Time to live in seconds. */ - private $ttl; + private ?int $ttl; /** * List of available options: * * prefix: The prefix to use for the keys in order to avoid collision on the Redis server * * ttl: The time to live in seconds. * - * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis - * * @throws \InvalidArgumentException When unsupported client or options are passed */ - public function __construct($redis, array $options = []) + public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis, array $options = []) { - if ( - !$redis instanceof \Redis && - !$redis instanceof \RedisArray && - !$redis instanceof \RedisCluster && - !$redis instanceof \Predis\ClientInterface && - !$redis instanceof RedisProxy && - !$redis instanceof RedisClusterProxy - ) { - throw new \InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, \is_object($redis) ? \get_class($redis) : \gettype($redis))); - } - if ($diff = array_diff(array_keys($options), ['prefix', 'ttl'])) { throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff))); } @@ -79,7 +66,7 @@ protected function doRead(string $sessionId): string */ protected function doWrite(string $sessionId, string $data): bool { - $result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')), $data); + $result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')), $data); return $result && !$result instanceof ErrorInterface; } @@ -89,7 +76,19 @@ protected function doWrite(string $sessionId, string $data): bool */ protected function doDestroy(string $sessionId): bool { - $this->redis->del($this->prefix.$sessionId); + static $unlink = true; + + if ($unlink) { + try { + $unlink = false !== $this->redis->unlink($this->prefix.$sessionId); + } catch (\Throwable $e) { + $unlink = false; + } + } + + if (!$unlink) { + $this->redis->del($this->prefix.$sessionId); + } return true; } @@ -97,24 +96,19 @@ protected function doDestroy(string $sessionId): bool /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function close(): bool { return true; } - /** - * {@inheritdoc} - */ - public function gc($maxlifetime): bool + public function gc(int $maxlifetime): int|false { - return true; + return 0; } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { - return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime'))); + return $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime'))); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php index a5ebd29eb..19ff94c81 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php @@ -21,13 +21,10 @@ */ class SessionHandlerFactory { - /** - * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy|\Memcached|\PDO|string $connection Connection or DSN - */ - public static function createHandler($connection): AbstractSessionHandler + public static function createHandler(object|string $connection): AbstractSessionHandler { - if (!\is_string($connection) && !\is_object($connection)) { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a string or a connection object, "%s" given.', __METHOD__, \gettype($connection))); + if ($options = \is_string($connection) ? parse_url($connection) : false) { + parse_str($options['query'] ?? '', $options); } switch (true) { @@ -46,38 +43,40 @@ public static function createHandler($connection): AbstractSessionHandler return new PdoSessionHandler($connection); case !\is_string($connection): - throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', \get_class($connection))); - case 0 === strpos($connection, 'file://'): - return new StrictSessionHandler(new NativeFileSessionHandler(substr($connection, 7))); + throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', get_debug_type($connection))); + case str_starts_with($connection, 'file://'): + $savePath = substr($connection, 7); - case 0 === strpos($connection, 'redis:'): - case 0 === strpos($connection, 'rediss:'): - case 0 === strpos($connection, 'memcached:'): + return new StrictSessionHandler(new NativeFileSessionHandler('' === $savePath ? null : $savePath)); + + case str_starts_with($connection, 'redis:'): + case str_starts_with($connection, 'rediss:'): + case str_starts_with($connection, 'memcached:'): if (!class_exists(AbstractAdapter::class)) { throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); } - $handlerClass = 0 === strpos($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; + $handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); - return new $handlerClass($connection); + return new $handlerClass($connection, array_intersect_key($options ?: [], ['prefix' => 1, 'ttl' => 1])); - case 0 === strpos($connection, 'pdo_oci://'): + case str_starts_with($connection, 'pdo_oci://'): if (!class_exists(DriverManager::class)) { throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection)); } $connection = DriverManager::getConnection(['url' => $connection])->getWrappedConnection(); // no break; - case 0 === strpos($connection, 'mssql://'): - case 0 === strpos($connection, 'mysql://'): - case 0 === strpos($connection, 'mysql2://'): - case 0 === strpos($connection, 'pgsql://'): - case 0 === strpos($connection, 'postgres://'): - case 0 === strpos($connection, 'postgresql://'): - case 0 === strpos($connection, 'sqlsrv://'): - case 0 === strpos($connection, 'sqlite://'): - case 0 === strpos($connection, 'sqlite3://'): - return new PdoSessionHandler($connection); + case str_starts_with($connection, 'mssql://'): + case str_starts_with($connection, 'mysql://'): + case str_starts_with($connection, 'mysql2://'): + case str_starts_with($connection, 'pgsql://'): + case str_starts_with($connection, 'postgres://'): + case str_starts_with($connection, 'postgresql://'): + case str_starts_with($connection, 'sqlsrv://'): + case str_starts_with($connection, 'sqlite://'): + case str_starts_with($connection, 'sqlite3://'): + return new PdoSessionHandler($connection, $options ?: []); } throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', $connection)); diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php index 4292a3b2f..f507d9269 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php @@ -18,22 +18,29 @@ */ class StrictSessionHandler extends AbstractSessionHandler { - private $handler; - private $doDestroy; + private \SessionHandlerInterface $handler; + private bool $doDestroy; public function __construct(\SessionHandlerInterface $handler) { if ($handler instanceof \SessionUpdateTimestampHandlerInterface) { - throw new \LogicException(sprintf('"%s" is already an instance of "SessionUpdateTimestampHandlerInterface", you cannot wrap it with "%s".', \get_class($handler), self::class)); + throw new \LogicException(sprintf('"%s" is already an instance of "SessionUpdateTimestampHandlerInterface", you cannot wrap it with "%s".', get_debug_type($handler), self::class)); } $this->handler = $handler; } /** - * @return bool + * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler. + * + * @internal */ - public function open($savePath, $sessionName) + public function isWrapper(): bool + { + return $this->handler instanceof \SessionHandler; + } + + public function open(string $savePath, string $sessionName): bool { parent::open($savePath, $sessionName); @@ -43,15 +50,12 @@ public function open($savePath, $sessionName) /** * {@inheritdoc} */ - protected function doRead(string $sessionId) + protected function doRead(string $sessionId): string { return $this->handler->read($sessionId); } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { return $this->write($sessionId, $data); } @@ -59,15 +63,12 @@ public function updateTimestamp($sessionId, $data) /** * {@inheritdoc} */ - protected function doWrite(string $sessionId, string $data) + protected function doWrite(string $sessionId, string $data): bool { return $this->handler->write($sessionId, $data); } - /** - * @return bool - */ - public function destroy($sessionId) + public function destroy(string $sessionId): bool { $this->doDestroy = true; $destroyed = parent::destroy($sessionId); @@ -78,25 +79,19 @@ public function destroy($sessionId) /** * {@inheritdoc} */ - protected function doDestroy(string $sessionId) + protected function doDestroy(string $sessionId): bool { $this->doDestroy = false; return $this->handler->destroy($sessionId); } - /** - * @return bool - */ - public function close() + public function close(): bool { return $this->handler->close(); } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { return $this->handler->gc($maxlifetime); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MetadataBag.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MetadataBag.php index c79ee023c..63bb93a9b 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MetadataBag.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MetadataBag.php @@ -22,19 +22,12 @@ */ class MetadataBag implements SessionBagInterface { - const CREATED = 'c'; - const UPDATED = 'u'; - const LIFETIME = 'l'; + public const CREATED = 'c'; + public const UPDATED = 'u'; + public const LIFETIME = 'l'; - /** - * @var string - */ - private $name = '__metadata'; - - /** - * @var string - */ - private $storageKey; + private string $name = '__metadata'; + private string $storageKey; /** * @var array @@ -43,15 +36,10 @@ class MetadataBag implements SessionBagInterface /** * Unix timestamp. - * - * @var int */ - private $lastUsed; + private int $lastUsed; - /** - * @var int - */ - private $updateThreshold; + private int $updateThreshold; /** * @param string $storageKey The key used to store bag in the session @@ -84,10 +72,8 @@ public function initialize(array &$array) /** * Gets the lifetime that the session cookie was set with. - * - * @return int */ - public function getLifetime() + public function getLifetime(): int { return $this->meta[self::LIFETIME]; } @@ -108,7 +94,7 @@ public function stampNew(int $lifetime = null) /** * {@inheritdoc} */ - public function getStorageKey() + public function getStorageKey(): string { return $this->storageKey; } @@ -118,7 +104,7 @@ public function getStorageKey() * * @return int Unix timestamp */ - public function getCreated() + public function getCreated(): int { return $this->meta[self::CREATED]; } @@ -128,7 +114,7 @@ public function getCreated() * * @return int Unix timestamp */ - public function getLastUsed() + public function getLastUsed(): int { return $this->lastUsed; } @@ -136,15 +122,16 @@ public function getLastUsed() /** * {@inheritdoc} */ - public function clear() + public function clear(): mixed { // nothing to do + return null; } /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->name; } @@ -161,6 +148,6 @@ private function stampCreated(int $lifetime = null): void { $timeStamp = time(); $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp; - $this->meta[self::LIFETIME] = (null === $lifetime) ? ini_get('session.cookie_lifetime') : $lifetime; + $this->meta[self::LIFETIME] = $lifetime ?? (int) \ini_get('session.cookie_lifetime'); } } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php index 0201504c9..8495f8ff5 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php @@ -76,7 +76,7 @@ public function setSessionData(array $array) /** * {@inheritdoc} */ - public function start() + public function start(): bool { if ($this->started) { return true; @@ -94,7 +94,7 @@ public function start() /** * {@inheritdoc} */ - public function regenerate(bool $destroy = false, int $lifetime = null) + public function regenerate(bool $destroy = false, int $lifetime = null): bool { if (!$this->started) { $this->start(); @@ -109,7 +109,7 @@ public function regenerate(bool $destroy = false, int $lifetime = null) /** * {@inheritdoc} */ - public function getId() + public function getId(): string { return $this->id; } @@ -129,7 +129,7 @@ public function setId(string $id) /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->name; } @@ -183,7 +183,7 @@ public function registerBag(SessionBagInterface $bag) /** * {@inheritdoc} */ - public function getBag(string $name) + public function getBag(string $name): SessionBagInterface { if (!isset($this->bags[$name])) { throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name)); @@ -199,7 +199,7 @@ public function getBag(string $name) /** * {@inheritdoc} */ - public function isStarted() + public function isStarted(): bool { return $this->started; } @@ -215,10 +215,8 @@ public function setMetadataBag(MetadataBag $bag = null) /** * Gets the MetadataBag. - * - * @return MetadataBag */ - public function getMetadataBag() + public function getMetadataBag(): MetadataBag { return $this->metadataBag; } @@ -228,10 +226,8 @@ public function getMetadataBag() * * This doesn't need to be particularly cryptographically secure since this is just * a mock. - * - * @return string */ - protected function generateId() + protected function generateId(): string { return hash('sha256', uniqid('ss_mock_', true)); } @@ -242,7 +238,7 @@ protected function loadSession() foreach ($bags as $bag) { $key = $bag->getStorageKey(); - $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : []; + $this->data[$key] = $this->data[$key] ?? []; $bag->initialize($this->data[$key]); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php index ab8b86402..d5fbd52af 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php @@ -13,7 +13,8 @@ /** * MockFileSessionStorage is used to mock sessions for - * functional testing when done in a single PHP process. + * functional testing where you may need to persist session data + * across separate PHP processes. * * No PHP session is actually started since a session can be initialized * and shutdown only once per PHP execution cycle and this class does @@ -24,10 +25,10 @@ */ class MockFileSessionStorage extends MockArraySessionStorage { - private $savePath; + private string $savePath; /** - * @param string $savePath Path of directory to save session files + * @param string|null $savePath Path of directory to save session files */ public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null) { @@ -47,7 +48,7 @@ public function __construct(string $savePath = null, string $name = 'MOCKSESSID' /** * {@inheritdoc} */ - public function start() + public function start(): bool { if ($this->started) { return true; @@ -67,7 +68,7 @@ public function start() /** * {@inheritdoc} */ - public function regenerate(bool $destroy = false, int $lifetime = null) + public function regenerate(bool $destroy = false, int $lifetime = null): bool { if (!$this->started) { $this->start(); @@ -102,7 +103,10 @@ public function save() try { if ($data) { - file_put_contents($this->getFilePath(), serialize($data)); + $path = $this->getFilePath(); + $tmp = $path.bin2hex(random_bytes(6)); + file_put_contents($tmp, serialize($data)); + rename($tmp, $path); } else { $this->destroy(); } @@ -110,9 +114,8 @@ public function save() $this->data = $data; } - // this is needed for Silex, where the session object is re-used across requests - // in functional tests. In Symfony, the container is rebooted, so we don't have - // this issue + // this is needed when the session object is re-used across multiple requests + // in functional tests. $this->started = false; } @@ -122,8 +125,11 @@ public function save() */ private function destroy(): void { - if (is_file($this->getFilePath())) { + set_error_handler(static function () {}); + try { unlink($this->getFilePath()); + } finally { + restore_error_handler(); } } @@ -140,8 +146,14 @@ private function getFilePath(): string */ private function read(): void { - $filePath = $this->getFilePath(); - $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : []; + set_error_handler(static function () {}); + try { + $data = file_get_contents($this->getFilePath()); + } finally { + restore_error_handler(); + } + + $this->data = $data ? unserialize($data) : []; $this->loadSession(); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorageFactory.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorageFactory.php new file mode 100644 index 000000000..c354d12ae --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/MockFileSessionStorageFactory.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +// Help opcache.preload discover always-needed symbols +class_exists(MockFileSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class MockFileSessionStorageFactory implements SessionStorageFactoryInterface +{ + private ?string $savePath; + private string $name; + private $metaBag; + + /** + * @see MockFileSessionStorage constructor. + */ + public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null) + { + $this->savePath = $savePath; + $this->name = $name; + $this->metaBag = $metaBag; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + return new MockFileSessionStorage($this->savePath, $this->name, $this->metaBag); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorage.php index 268f9784e..b281a809c 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorage.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @@ -12,7 +12,6 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; -use Symfony\Component\HttpFoundation\Session\SessionUtils; use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; @@ -54,11 +53,6 @@ class NativeSessionStorage implements SessionStorageInterface */ protected $metadataBag; - /** - * @var string|null - */ - private $emulateSameSite; - /** * Depending on how you want the storage driver to behave you probably * want to override this constructor entirely. @@ -86,25 +80,16 @@ class NativeSessionStorage implements SessionStorageInterface * name, "PHPSESSID" * referer_check, "" * serialize_handler, "php" - * use_strict_mode, "0" + * use_strict_mode, "1" * use_cookies, "1" * use_only_cookies, "1" * use_trans_sid, "0" - * upload_progress.enabled, "1" - * upload_progress.cleanup, "1" - * upload_progress.prefix, "upload_progress_" - * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS" - * upload_progress.freq, "1%" - * upload_progress.min-freq, "1" - * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" * sid_length, "32" * sid_bits_per_character, "5" * trans_sid_hosts, $_SERVER['HTTP_HOST'] * trans_sid_tags, "a=href,area=href,frame=src,form=" - * - * @param AbstractProxy|\SessionHandlerInterface|null $handler */ - public function __construct(array $options = [], $handler = null, MetadataBag $metaBag = null) + public function __construct(array $options = [], AbstractProxy|\SessionHandlerInterface $handler = null, MetadataBag $metaBag = null) { if (!\extension_loaded('session')) { throw new \LogicException('PHP extension "session" is required.'); @@ -127,10 +112,8 @@ public function __construct(array $options = [], $handler = null, MetadataBag $m /** * Gets the save handler instance. - * - * @return AbstractProxy|\SessionHandlerInterface */ - public function getSaveHandler() + public function getSaveHandler(): AbstractProxy|\SessionHandlerInterface { return $this->saveHandler; } @@ -138,32 +121,61 @@ public function getSaveHandler() /** * {@inheritdoc} */ - public function start() + public function start(): bool { if ($this->started) { return true; } - if (PHP_SESSION_ACTIVE === session_status()) { + if (\PHP_SESSION_ACTIVE === session_status()) { throw new \RuntimeException('Failed to start the session: already started by PHP.'); } - if (filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) { + if (filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) { throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); } + $sessionId = $_COOKIE[session_name()] ?? null; + /* + * Explanation of the session ID regular expression: `/^[a-zA-Z0-9,-]{22,250}$/`. + * + * ---------- Part 1 + * + * The part `[a-zA-Z0-9,-]` is related to the PHP ini directive `session.sid_bits_per_character` defined as 6. + * See https://www.php.net/manual/en/session.configuration.php#ini.session.sid-bits-per-character. + * Allowed values are integers such as: + * - 4 for range `a-f0-9` + * - 5 for range `a-v0-9` + * - 6 for range `a-zA-Z0-9,-` + * + * ---------- Part 2 + * + * The part `{22,250}` is related to the PHP ini directive `session.sid_length`. + * See https://www.php.net/manual/en/session.configuration.php#ini.session.sid-length. + * Allowed values are integers between 22 and 256, but we use 250 for the max. + * + * Where does the 250 come from? + * - The length of Windows and Linux filenames is limited to 255 bytes. Then the max must not exceed 255. + * - The session filename prefix is `sess_`, a 5 bytes string. Then the max must not exceed 255 - 5 = 250. + * + * ---------- Conclusion + * + * The parts 1 and 2 prevent the warning below: + * `PHP Warning: SessionHandler::read(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed.` + * + * The part 2 prevents the warning below: + * `PHP Warning: SessionHandler::read(): open(filepath, O_RDWR) failed: No such file or directory (2).` + */ + if ($sessionId && $this->saveHandler instanceof AbstractProxy && 'files' === $this->saveHandler->getSaveHandlerName() && !preg_match('/^[a-zA-Z0-9,-]{22,250}$/', $sessionId)) { + // the session ID in the header is invalid, create a new one + session_id(session_create_id()); + } + // ok to try and start the session if (!session_start()) { throw new \RuntimeException('Failed to start the session.'); } - if (null !== $this->emulateSameSite) { - $originalCookie = SessionUtils::popSessionCookie(session_name(), session_id()); - if (null !== $originalCookie) { - header(sprintf('%s; SameSite=%s', $originalCookie, $this->emulateSameSite), false); - } - } - $this->loadSession(); return true; @@ -172,7 +184,7 @@ public function start() /** * {@inheritdoc} */ - public function getId() + public function getId(): string { return $this->saveHandler->getId(); } @@ -188,7 +200,7 @@ public function setId(string $id) /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return $this->saveHandler->getName(); } @@ -204,10 +216,10 @@ public function setName(string $name) /** * {@inheritdoc} */ - public function regenerate(bool $destroy = false, int $lifetime = null) + public function regenerate(bool $destroy = false, int $lifetime = null): bool { // Cannot regenerate the session ID for non-active sessions. - if (PHP_SESSION_ACTIVE !== session_status()) { + if (\PHP_SESSION_ACTIVE !== session_status()) { return false; } @@ -215,28 +227,17 @@ public function regenerate(bool $destroy = false, int $lifetime = null) return false; } - if (null !== $lifetime) { + if (null !== $lifetime && $lifetime != \ini_get('session.cookie_lifetime')) { + $this->save(); ini_set('session.cookie_lifetime', $lifetime); + $this->start(); } if ($destroy) { $this->metadataBag->stampNew(); } - $isRegenerated = session_regenerate_id($destroy); - - // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it. - // @see https://bugs.php.net/70013 - $this->loadSession(); - - if (null !== $this->emulateSameSite) { - $originalCookie = SessionUtils::popSessionCookie(session_name(), session_id()); - if (null !== $originalCookie) { - header(sprintf('%s; SameSite=%s', $originalCookie, $this->emulateSameSite), false); - } - } - - return $isRegenerated; + return session_regenerate_id($destroy); } /** @@ -252,13 +253,13 @@ public function save() unset($_SESSION[$key]); } } - if ([$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) { + if ($_SESSION && [$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) { unset($_SESSION[$key]); } // Register error handler to add information about the current save handler $previousHandler = set_error_handler(function ($type, $msg, $file, $line) use (&$previousHandler) { - if (E_WARNING === $type && 0 === strpos($msg, 'session_write_close():')) { + if (\E_WARNING === $type && str_starts_with($msg, 'session_write_close():')) { $handler = $this->saveHandler instanceof SessionHandlerProxy ? $this->saveHandler->getHandler() : $this->saveHandler; $msg = sprintf('session_write_close(): Failed to write session data with "%s" handler', \get_class($handler)); } @@ -313,7 +314,7 @@ public function registerBag(SessionBagInterface $bag) /** * {@inheritdoc} */ - public function getBag(string $name) + public function getBag(string $name): SessionBagInterface { if (!isset($this->bags[$name])) { throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name)); @@ -339,10 +340,8 @@ public function setMetadataBag(MetadataBag $metaBag = null) /** * Gets the MetadataBag. - * - * @return MetadataBag */ - public function getMetadataBag() + public function getMetadataBag(): MetadataBag { return $this->metadataBag; } @@ -350,7 +349,7 @@ public function getMetadataBag() /** * {@inheritdoc} */ - public function isStarted() + public function isStarted(): bool { return $this->started; } @@ -367,7 +366,7 @@ public function isStarted() */ public function setOptions(array $options) { - if (headers_sent() || PHP_SESSION_ACTIVE === session_status()) { + if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { return; } @@ -377,21 +376,16 @@ public function setOptions(array $options) 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'lazy_write', 'name', 'referer_check', 'serialize_handler', 'use_strict_mode', 'use_cookies', - 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', - 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', - 'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags', + 'use_only_cookies', 'use_trans_sid', 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags', ]); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { - if ('cookie_samesite' === $key && \PHP_VERSION_ID < 70300) { - // PHP < 7.3 does not support same_site cookies. We will emulate it in - // the start() method instead. - $this->emulateSameSite = $value; + if ('cookie_secure' === $key && 'auto' === $value) { continue; } - ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value); + ini_set('session.'.$key, $value); } } } @@ -412,11 +406,9 @@ public function setOptions(array $options) * @see https://php.net/sessionhandlerinterface * @see https://php.net/sessionhandler * - * @param AbstractProxy|\SessionHandlerInterface|null $saveHandler - * * @throws \InvalidArgumentException */ - public function setSaveHandler($saveHandler = null) + public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandler = null) { if (!$saveHandler instanceof AbstractProxy && !$saveHandler instanceof \SessionHandlerInterface && @@ -432,7 +424,7 @@ public function setSaveHandler($saveHandler = null) } $this->saveHandler = $saveHandler; - if (headers_sent() || PHP_SESSION_ACTIVE === session_status()) { + if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { return; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorageFactory.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorageFactory.php new file mode 100644 index 000000000..ea6c7de1e --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/NativeSessionStorageFactory.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\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; + +// Help opcache.preload discover always-needed symbols +class_exists(NativeSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class NativeSessionStorageFactory implements SessionStorageFactoryInterface +{ + private array $options; + private $handler; + private $metaBag; + private bool $secure; + + /** + * @see NativeSessionStorage constructor. + */ + public function __construct(array $options = [], AbstractProxy|\SessionHandlerInterface $handler = null, MetadataBag $metaBag = null, bool $secure = false) + { + $this->options = $options; + $this->handler = $handler; + $this->metaBag = $metaBag; + $this->secure = $secure; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + $storage = new NativeSessionStorage($this->options, $this->handler, $this->metaBag); + if ($this->secure && $request && $request->isSecure()) { + $storage->setOptions(['cookie_secure' => true]); + } + + return $storage; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php index 72dbef134..276ed318a 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php @@ -20,10 +20,7 @@ */ class PhpBridgeSessionStorage extends NativeSessionStorage { - /** - * @param AbstractProxy|\SessionHandlerInterface|null $handler - */ - public function __construct($handler = null, MetadataBag $metaBag = null) + public function __construct(AbstractProxy|\SessionHandlerInterface $handler = null, MetadataBag $metaBag = null) { if (!\extension_loaded('session')) { throw new \LogicException('PHP extension "session" is required.'); @@ -36,7 +33,7 @@ public function __construct($handler = null, MetadataBag $metaBag = null) /** * {@inheritdoc} */ - public function start() + public function start(): bool { if ($this->started) { return true; diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorageFactory.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorageFactory.php new file mode 100644 index 000000000..cce1ec6c3 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorageFactory.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\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; + +// Help opcache.preload discover always-needed symbols +class_exists(PhpBridgeSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class PhpBridgeSessionStorageFactory implements SessionStorageFactoryInterface +{ + private $handler; + private $metaBag; + private bool $secure; + + public function __construct(AbstractProxy|\SessionHandlerInterface $handler = null, MetadataBag $metaBag = null, bool $secure = false) + { + $this->handler = $handler; + $this->metaBag = $metaBag; + $this->secure = $secure; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + $storage = new PhpBridgeSessionStorage($this->handler, $this->metaBag); + if ($this->secure && $request && $request->isSecure()) { + $storage->setOptions(['cookie_secure' => true]); + } + + return $storage; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php index e7be22c01..1845ee2c9 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php @@ -30,50 +30,40 @@ abstract class AbstractProxy /** * Gets the session.save_handler name. - * - * @return string|null */ - public function getSaveHandlerName() + public function getSaveHandlerName(): ?string { return $this->saveHandlerName; } /** * Is this proxy handler and instance of \SessionHandlerInterface. - * - * @return bool */ - public function isSessionHandlerInterface() + public function isSessionHandlerInterface(): bool { return $this instanceof \SessionHandlerInterface; } /** * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler. - * - * @return bool */ - public function isWrapper() + public function isWrapper(): bool { return $this->wrapper; } /** * Has a session started? - * - * @return bool */ - public function isActive() + public function isActive(): bool { - return PHP_SESSION_ACTIVE === session_status(); + return \PHP_SESSION_ACTIVE === session_status(); } /** * Gets the session ID. - * - * @return string */ - public function getId() + public function getId(): string { return session_id(); } @@ -94,10 +84,8 @@ public function setId(string $id) /** * Gets the session name. - * - * @return string */ - public function getName() + public function getName(): string { return session_name(); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php index de4f550ba..c292e58f0 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -11,6 +11,8 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; + /** * @author Drak */ @@ -21,80 +23,53 @@ class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterf public function __construct(\SessionHandlerInterface $handler) { $this->handler = $handler; - $this->wrapper = ($handler instanceof \SessionHandler); - $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user'; + $this->wrapper = $handler instanceof \SessionHandler; + $this->saveHandlerName = $this->wrapper || ($handler instanceof StrictSessionHandler && $handler->isWrapper()) ? \ini_get('session.save_handler') : 'user'; } - /** - * @return \SessionHandlerInterface - */ - public function getHandler() + public function getHandler(): \SessionHandlerInterface { return $this->handler; } // \SessionHandlerInterface - /** - * @return bool - */ - public function open($savePath, $sessionName) + public function open(string $savePath, string $sessionName): bool { - return (bool) $this->handler->open($savePath, $sessionName); + return $this->handler->open($savePath, $sessionName); } - /** - * @return bool - */ - public function close() + public function close(): bool { - return (bool) $this->handler->close(); + return $this->handler->close(); } - /** - * @return string - */ - public function read($sessionId) + public function read(string $sessionId): string|false { - return (string) $this->handler->read($sessionId); + return $this->handler->read($sessionId); } - /** - * @return bool - */ - public function write($sessionId, $data) + public function write(string $sessionId, string $data): bool { - return (bool) $this->handler->write($sessionId, $data); + return $this->handler->write($sessionId, $data); } - /** - * @return bool - */ - public function destroy($sessionId) + public function destroy(string $sessionId): bool { - return (bool) $this->handler->destroy($sessionId); + return $this->handler->destroy($sessionId); } - /** - * @return bool - */ - public function gc($maxlifetime) + public function gc(int $maxlifetime): int|false { - return (bool) $this->handler->gc($maxlifetime); + return $this->handler->gc($maxlifetime); } - /** - * @return bool - */ - public function validateId($sessionId) + public function validateId(string $sessionId): bool { return !$this->handler instanceof \SessionUpdateTimestampHandlerInterface || $this->handler->validateId($sessionId); } - /** - * @return bool - */ - public function updateTimestamp($sessionId, $data) + public function updateTimestamp(string $sessionId, string $data): bool { return $this->handler instanceof \SessionUpdateTimestampHandlerInterface ? $this->handler->updateTimestamp($sessionId, $data) : $this->write($sessionId, $data); } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageFactoryInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageFactoryInterface.php new file mode 100644 index 000000000..d03f0da4c --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageFactoryInterface.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\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Jérémy Derussé + */ +interface SessionStorageFactoryInterface +{ + /** + * Creates a new instance of SessionStorageInterface. + */ + public function createStorage(?Request $request): SessionStorageInterface; +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageInterface.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageInterface.php index eb8e8ff23..36839e69f 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageInterface.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Session/Storage/SessionStorageInterface.php @@ -24,25 +24,19 @@ interface SessionStorageInterface /** * Starts the session. * - * @return bool True if started - * * @throws \RuntimeException if something goes wrong starting the session */ - public function start(); + public function start(): bool; /** * Checks if the session is started. - * - * @return bool True if started, false otherwise */ - public function isStarted(); + public function isStarted(): bool; /** * Returns the session ID. - * - * @return string The session ID or empty */ - public function getId(); + public function getId(): string; /** * Sets the session ID. @@ -51,10 +45,8 @@ public function setId(string $id); /** * Returns the session name. - * - * @return string The session name */ - public function getName(); + public function getName(): string; /** * Sets the session name. @@ -86,11 +78,9 @@ public function setName(string $name); * to expire with browser session. Time is in seconds, and is * not a Unix timestamp. * - * @return bool True if session regenerated, false if error - * * @throws \RuntimeException If an error occurs while regenerating this storage */ - public function regenerate(bool $destroy = false, int $lifetime = null); + public function regenerate(bool $destroy = false, int $lifetime = null): bool; /** * Force the session to be saved and closed. @@ -113,19 +103,14 @@ public function clear(); /** * Gets a SessionBagInterface by name. * - * @return SessionBagInterface - * * @throws \InvalidArgumentException If the bag does not exist */ - public function getBag(string $name); + public function getBag(string $name): SessionBagInterface; /** * Registers a SessionBagInterface for use. */ public function registerBag(SessionBagInterface $bag); - /** - * @return MetadataBag - */ - public function getMetadataBag(); + public function getMetadataBag(): MetadataBag; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/StreamedResponse.php b/lam/lib/3rdParty/composer/symfony/http-foundation/StreamedResponse.php index 65ec2d984..4a6fbe156 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/StreamedResponse.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/StreamedResponse.php @@ -28,7 +28,7 @@ class StreamedResponse extends Response { protected $callback; protected $streamed; - private $headersSent; + private bool $headersSent; public function __construct(callable $callback = null, int $status = 200, array $headers = []) { @@ -41,24 +41,12 @@ public function __construct(callable $callback = null, int $status = 200, array $this->headersSent = false; } - /** - * Factory method for chainability. - * - * @param callable|null $callback A valid PHP callback or null to set it later - * - * @return static - */ - public static function create($callback = null, int $status = 200, array $headers = []) - { - return new static($callback, $status, $headers); - } - /** * Sets the PHP callback associated with this Response. * * @return $this */ - public function setCallback(callable $callback) + public function setCallback(callable $callback): static { $this->callback = $callback; @@ -72,7 +60,7 @@ public function setCallback(callable $callback) * * @return $this */ - public function sendHeaders() + public function sendHeaders(): static { if ($this->headersSent) { return $this; @@ -90,7 +78,7 @@ public function sendHeaders() * * @return $this */ - public function sendContent() + public function sendContent(): static { if ($this->streamed) { return $this; @@ -114,7 +102,7 @@ public function sendContent() * * @return $this */ - public function setContent(?string $content) + public function setContent(?string $content): static { if (null !== $content) { throw new \LogicException('The content cannot be set on a StreamedResponse instance.'); @@ -128,7 +116,7 @@ public function setContent(?string $content) /** * {@inheritdoc} */ - public function getContent() + public function getContent(): string|false { return false; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php index cb216ea12..534c1d138 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php @@ -16,8 +16,8 @@ final class RequestAttributeValueSame extends Constraint { - private $name; - private $value; + private string $name; + private string $value; public function __construct(string $name, string $value) { diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php index 554e1a160..f62a4cffb 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php @@ -17,10 +17,10 @@ final class ResponseCookieValueSame extends Constraint { - private $name; - private $value; - private $path; - private $domain; + private string $name; + private string $value; + private string $path; + private ?string $domain; public function __construct(string $name, string $value, string $path = '/', string $domain = null) { @@ -59,7 +59,7 @@ protected function matches($response): bool return false; } - return $this->value === $cookie->getValue(); + return $this->value === (string) $cookie->getValue(); } /** diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php new file mode 100644 index 000000000..cb9699c32 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseFormatSame.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\HttpFoundation\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Asserts that the response is in the given format. + * + * @author Kévin Dunglas + */ +final class ResponseFormatSame extends Constraint +{ + private $request; + private ?string $format; + + public function __construct(Request $request, ?string $format) + { + $this->request = $request; + $this->format = $format; + } + + /** + * {@inheritdoc} + */ + public function toString(): string + { + return 'format is '.($this->format ?? 'null'); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function matches($response): bool + { + return $this->format === $this->request->getFormat($response->headers->get('Content-Type')); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function failureDescription($response): string + { + return 'the Response '.$this->toString(); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function additionalFailureDescription($response): string + { + return (string) $response; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php index eae9e271b..47a091b08 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php @@ -17,9 +17,9 @@ final class ResponseHasCookie extends Constraint { - private $name; - private $path; - private $domain; + private string $name; + private string $path; + private ?string $domain; public function __construct(string $name, string $path = '/', string $domain = null) { diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php index 68ad8273f..1e028976e 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php @@ -16,7 +16,7 @@ final class ResponseHasHeader extends Constraint { - private $headerName; + private string $headerName; public function __construct(string $headerName) { diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php index a27d0c73f..dc96bec80 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php @@ -16,8 +16,8 @@ final class ResponseHeaderSame extends Constraint { - private $headerName; - private $expectedValue; + private string $headerName; + private string $expectedValue; public function __construct(string $headerName, string $expectedValue) { diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php new file mode 100644 index 000000000..880c7818b --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\HttpFoundation\Response; + +final class ResponseIsUnprocessable extends Constraint +{ + /** + * {@inheritdoc} + */ + public function toString(): string + { + return 'is unprocessable'; + } + + /** + * @param Response $other + * + * {@inheritdoc} + */ + protected function matches($other): bool + { + return Response::HTTP_UNPROCESSABLE_ENTITY === $other->getStatusCode(); + } + + /** + * @param Response $other + * + * {@inheritdoc} + */ + protected function failureDescription($other): string + { + return 'the Response '.$this->toString(); + } + + /** + * @param Response $other + * + * {@inheritdoc} + */ + protected function additionalFailureDescription($other): string + { + return (string) $other; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php index 72bb000b8..8d2ce1228 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php @@ -16,7 +16,7 @@ final class ResponseStatusCodeSame extends Constraint { - private $statusCode; + private int $statusCode; public function __construct(int $statusCode) { diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/UrlHelper.php b/lam/lib/3rdParty/composer/symfony/http-foundation/UrlHelper.php index f114c0a9f..c15f101cd 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/UrlHelper.php +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/UrlHelper.php @@ -31,11 +31,11 @@ public function __construct(RequestStack $requestStack, RequestContext $requestC public function getAbsoluteUrl(string $path): string { - if (false !== strpos($path, '://') || '//' === substr($path, 0, 2)) { + if (str_contains($path, '://') || '//' === substr($path, 0, 2)) { return $path; } - if (null === $request = $this->requestStack->getMasterRequest()) { + if (null === $request = $this->requestStack->getMainRequest()) { return $this->getAbsoluteUrlFromContext($path); } @@ -60,11 +60,11 @@ public function getAbsoluteUrl(string $path): string public function getRelativePath(string $path): string { - if (false !== strpos($path, '://') || '//' === substr($path, 0, 2)) { + if (str_contains($path, '://') || '//' === substr($path, 0, 2)) { return $path; } - if (null === $request = $this->requestStack->getMasterRequest()) { + if (null === $request = $this->requestStack->getMainRequest()) { return $path; } diff --git a/lam/lib/3rdParty/composer/symfony/http-foundation/composer.json b/lam/lib/3rdParty/composer/symfony/http-foundation/composer.json index fcec68c36..42405d957 100644 --- a/lam/lib/3rdParty/composer/symfony/http-foundation/composer.json +++ b/lam/lib/3rdParty/composer/symfony/http-foundation/composer.json @@ -1,7 +1,7 @@ { "name": "symfony/http-foundation", "type": "library", - "description": "Symfony HttpFoundation Component", + "description": "Defines an object-oriented layer for the HTTP specification", "keywords": [], "homepage": "https://symfony.com", "license": "MIT", @@ -16,13 +16,21 @@ } ], "require": { - "php": "^7.2.5", - "symfony/mime": "^4.4|^5.0", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "^4.4|^5.0" + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest" : { + "symfony/mime": "To use the file extension guesser" }, "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }, @@ -30,10 +38,5 @@ "/Tests/" ] }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - } + "minimum-stability": "dev" } diff --git a/lam/lib/3rdParty/composer/symfony/mime/Address.php b/lam/lib/3rdParty/composer/symfony/mime/Address.php deleted file mode 100644 index ae83efd73..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Address.php +++ /dev/null @@ -1,149 +0,0 @@ - - * - * 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 $validator; - private static $encoder; - - private $address; - private $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)); - } - - if (null === self::$validator) { - 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 - { - if (null === self::$encoder) { - 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())); - } - - /** - * @param Address|string $address - */ - public static function create($address): self - { - if ($address instanceof self) { - return $address; - } - - if (!\is_string($address)) { - throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s" given).', get_debug_type($address))); - } - - if (false === strpos($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; - } - - /** - * @deprecated since Symfony 5.2, use "create()" instead. - */ - public static function fromString(string $string): self - { - trigger_deprecation('symfony/mime', '5.2', '"%s()" is deprecated, use "%s::create()" instead.', __METHOD__, __CLASS__); - - if (!str_contains($string, '<')) { - return new self($string, ''); - } - - if (!preg_match(self::FROM_STRING_PATTERN, $string, $matches)) { - throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, self::class)); - } - - return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"')); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/CHANGELOG.md b/lam/lib/3rdParty/composer/symfony/mime/CHANGELOG.md deleted file mode 100644 index f272346c9..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/CHANGELOG.md +++ /dev/null @@ -1,26 +0,0 @@ -CHANGELOG -========= - -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/lam/lib/3rdParty/composer/symfony/mime/CharacterStream.php b/lam/lib/3rdParty/composer/symfony/mime/CharacterStream.php deleted file mode 100644 index 238debde1..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/CharacterStream.php +++ /dev/null @@ -1,218 +0,0 @@ - - * - * 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 $data = ''; - private $dataSize = 0; - private $map = []; - private $charCount = 0; - private $currentPos = 0; - private $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 { - switch ($charset) { - // 16 bits - case 'ucs2': - case 'ucs-2': - case 'utf16': - case 'utf-16': - $this->fixedWidth = 2; - break; - - // 32 bits - case 'ucs4': - case 'ucs-4': - case 'utf32': - case 'utf-32': - $this->fixedWidth = 4; - break; - - // 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: - $this->fixedWidth = 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/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimOptions.php b/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimOptions.php deleted file mode 100644 index 171bb2583..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimOptions.php +++ /dev/null @@ -1,97 +0,0 @@ - - * - * 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 $options = []; - - public function toArray(): array - { - return $this->options; - } - - /** - * @return $this - */ - public function algorithm(string $algo): self - { - $this->options['algorithm'] = $algo; - - return $this; - } - - /** - * @return $this - */ - public function signatureExpirationDelay(int $show): self - { - $this->options['signature_expiration_delay'] = $show; - - return $this; - } - - /** - * @return $this - */ - public function bodyMaxLength(int $max): self - { - $this->options['body_max_length'] = $max; - - return $this; - } - - /** - * @return $this - */ - public function bodyShowLength(bool $show): self - { - $this->options['body_show_length'] = $show; - - return $this; - } - - /** - * @return $this - */ - public function headerCanon(string $canon): self - { - $this->options['header_canon'] = $canon; - - return $this; - } - - /** - * @return $this - */ - public function bodyCanon(string $canon): self - { - $this->options['body_canon'] = $canon; - - return $this; - } - - /** - * @return $this - */ - public function headersToIgnore(array $headers): self - { - $this->options['headers_to_ignore'] = $headers; - - return $this; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimSigner.php b/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimSigner.php deleted file mode 100644 index f0f7091ed..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Crypto/DkimSigner.php +++ /dev/null @@ -1,220 +0,0 @@ - - * - * 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 $key; - private $domainName; - private $selector; - private $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.'); - } - if (!$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/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMime.php b/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMime.php deleted file mode 100644 index cba95f210..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMime.php +++ /dev/null @@ -1,111 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeEncrypter.php b/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeEncrypter.php deleted file mode 100644 index 9081860d8..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeEncrypter.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * 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 $certs; - private $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://www.php.net/manual/en/openssl.ciphers.php - */ - public function __construct($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/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeSigner.php b/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeSigner.php deleted file mode 100644 index 5b94a454e..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Crypto/SMimeSigner.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * 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 $signCertificate; - private $signPrivateKey; - private $signOptions; - private $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/lam/lib/3rdParty/composer/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php b/lam/lib/3rdParty/composer/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php deleted file mode 100644 index 00eef94ee..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * 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 -{ - private $mimeTypesService; - private $mimeTypeGuesserTag; - - public function __construct(string $mimeTypesService = 'mime_types', string $mimeTypeGuesserTag = 'mime.mime_type_guesser') - { - if (0 < \func_num_args()) { - trigger_deprecation('symfony/mime', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->mimeTypesService = $mimeTypesService; - $this->mimeTypeGuesserTag = $mimeTypeGuesserTag; - } - - /** - * {@inheritdoc} - */ - public function process(ContainerBuilder $container) - { - if ($container->has($this->mimeTypesService)) { - $definition = $container->findDefinition($this->mimeTypesService); - foreach ($container->findTaggedServiceIds($this->mimeTypeGuesserTag, true) as $id => $attributes) { - $definition->addMethodCall('registerGuesser', [new Reference($id)]); - } - } - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Email.php b/lam/lib/3rdParty/composer/symfony/mime/Email.php deleted file mode 100644 index bd0a476c4..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Email.php +++ /dev/null @@ -1,630 +0,0 @@ - - * - * 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\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', - ]; - - private $text; - private $textCharset; - private $html; - private $htmlCharset; - private $attachments = []; - /** - * @var AbstractPart|null - */ - private $cachedBody; // 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) - { - return $this->setHeaderBody('Text', 'Subject', $subject); - } - - public function getSubject(): ?string - { - return $this->getHeaders()->getHeaderBody('Subject'); - } - - /** - * @return $this - */ - public function date(\DateTimeInterface $dateTime) - { - return $this->setHeaderBody('Date', 'Date', $dateTime); - } - - public function getDate(): ?\DateTimeImmutable - { - return $this->getHeaders()->getHeaderBody('Date'); - } - - /** - * @param Address|string $address - * - * @return $this - */ - public function returnPath($address) - { - return $this->setHeaderBody('Path', 'Return-Path', Address::create($address)); - } - - public function getReturnPath(): ?Address - { - return $this->getHeaders()->getHeaderBody('Return-Path'); - } - - /** - * @param Address|string $address - * - * @return $this - */ - public function sender($address) - { - return $this->setHeaderBody('Mailbox', 'Sender', Address::create($address)); - } - - public function getSender(): ?Address - { - return $this->getHeaders()->getHeaderBody('Sender'); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function addFrom(...$addresses) - { - return $this->addListAddressHeaderBody('From', $addresses); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function from(...$addresses) - { - return $this->setListAddressHeaderBody('From', $addresses); - } - - /** - * @return Address[] - */ - public function getFrom(): array - { - return $this->getHeaders()->getHeaderBody('From') ?: []; - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function addReplyTo(...$addresses) - { - return $this->addListAddressHeaderBody('Reply-To', $addresses); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function replyTo(...$addresses) - { - return $this->setListAddressHeaderBody('Reply-To', $addresses); - } - - /** - * @return Address[] - */ - public function getReplyTo(): array - { - return $this->getHeaders()->getHeaderBody('Reply-To') ?: []; - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function addTo(...$addresses) - { - return $this->addListAddressHeaderBody('To', $addresses); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function to(...$addresses) - { - return $this->setListAddressHeaderBody('To', $addresses); - } - - /** - * @return Address[] - */ - public function getTo(): array - { - return $this->getHeaders()->getHeaderBody('To') ?: []; - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function addCc(...$addresses) - { - return $this->addListAddressHeaderBody('Cc', $addresses); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function cc(...$addresses) - { - return $this->setListAddressHeaderBody('Cc', $addresses); - } - - /** - * @return Address[] - */ - public function getCc(): array - { - return $this->getHeaders()->getHeaderBody('Cc') ?: []; - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function addBcc(...$addresses) - { - return $this->addListAddressHeaderBody('Bcc', $addresses); - } - - /** - * @param Address|string ...$addresses - * - * @return $this - */ - public function bcc(...$addresses) - { - 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) - { - 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') - { - 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') - { - 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) - { - if (!\is_string($body) && !\is_resource($body)) { - throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body))); - } - - $this->cachedBody = null; - $this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => false]; - - return $this; - } - - /** - * @return $this - */ - public function attachFromPath(string $path, string $name = null, string $contentType = null) - { - $this->cachedBody = null; - $this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => false]; - - return $this; - } - - /** - * @param resource|string $body - * - * @return $this - */ - public function embed($body, string $name = null, string $contentType = null) - { - if (!\is_string($body) && !\is_resource($body)) { - throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body))); - } - - $this->cachedBody = null; - $this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => true]; - - return $this; - } - - /** - * @return $this - */ - public function embedFromPath(string $path, string $name = null, string $contentType = null) - { - $this->cachedBody = null; - $this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => true]; - - return $this; - } - - /** - * @return $this - */ - public function attachPart(DataPart $part) - { - $this->cachedBody = null; - $this->attachments[] = ['part' => $part]; - - return $this; - } - - /** - * @return array|DataPart[] - */ - public function getAttachments(): array - { - $parts = []; - foreach ($this->attachments as $attachment) { - $parts[] = $this->createDataPart($attachment); - } - - return $parts; - } - - public function getBody(): AbstractPart - { - if (null !== $body = parent::getBody()) { - return $body; - } - - return $this->generateBody(); - } - - public function ensureValidity() - { - if (null === $this->text && null === $this->html && !$this->attachments) { - throw new LogicException('A message must have a text or an HTML part or attachments.'); - } - - parent::ensureValidity(); - } - - /** - * 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->ensureValidity(); - - [$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(); - preg_match_all('(]*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+)))i', $html, $names); - $names = array_filter(array_unique(array_merge($names[2], $names[3]))); - } - - // usage of reflection is a temporary workaround for missing getters that will be added in 6.2 - $nameRef = new \ReflectionProperty(TextPart::class, 'name'); - $nameRef->setAccessible(true); - $otherParts = $relatedParts = []; - foreach ($this->attachments as $attachment) { - $part = $this->createDataPart($attachment); - if (isset($attachment['part'])) { - $attachment['name'] = $nameRef->getValue($part); - } - - $related = false; - foreach ($names as $name) { - if ($name !== $attachment['name']) { - continue; - } - if (isset($relatedParts[$name])) { - continue 2; - } - $part->setDisposition('inline'); - $html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html, $count); - if ($count) { - $related = true; - } - $part->setName($part->getContentId()); - - break; - } - - if ($related) { - $relatedParts[$attachment['name']] = $part; - } else { - $otherParts[] = $part; - } - } - if (null !== $htmlPart) { - $htmlPart = new TextPart($html, $this->htmlCharset, 'html'); - } - - return [$htmlPart, $otherParts, array_values($relatedParts)]; - } - - private function createDataPart(array $attachment): DataPart - { - if (isset($attachment['part'])) { - return $attachment['part']; - } - - if (isset($attachment['body'])) { - $part = new DataPart($attachment['body'], $attachment['name'] ?? null, $attachment['content-type'] ?? null); - } else { - $part = DataPart::fromPath($attachment['path'] ?? '', $attachment['name'] ?? null, $attachment['content-type'] ?? null); - } - if ($attachment['inline']) { - $part->asInline(); - } - - return $part; - } - - /** - * @return $this - */ - private function setHeaderBody(string $type, string $name, $body): object - { - $this->getHeaders()->setHeaderBody($type, $name, $body); - - return $this; - } - - private function addListAddressHeaderBody(string $name, array $addresses) - { - 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) - { - $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(); - } - - foreach ($this->attachments as $i => $attachment) { - if (isset($attachment['body']) && \is_resource($attachment['body'])) { - $this->attachments[$i]['body'] = (new TextPart($attachment['body']))->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/lam/lib/3rdParty/composer/symfony/mime/Encoder/AddressEncoderInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/AddressEncoderInterface.php deleted file mode 100644 index de477d884..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/AddressEncoderInterface.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64ContentEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64ContentEncoder.php deleted file mode 100644 index 440868af7..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64ContentEncoder.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64Encoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64Encoder.php deleted file mode 100644 index 710647857..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64Encoder.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64MimeHeaderEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64MimeHeaderEncoder.php deleted file mode 100644 index 5c06f6d9a..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/Base64MimeHeaderEncoder.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/ContentEncoderInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/ContentEncoderInterface.php deleted file mode 100644 index a45ad04c2..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/ContentEncoderInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/EightBitContentEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/EightBitContentEncoder.php deleted file mode 100644 index 82831209e..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/EightBitContentEncoder.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/EncoderInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/EncoderInterface.php deleted file mode 100644 index bbf6d4886..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/EncoderInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/IdnAddressEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/IdnAddressEncoder.php deleted file mode 100644 index b56e7e396..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/IdnAddressEncoder.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/MimeHeaderEncoderInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/MimeHeaderEncoderInterface.php deleted file mode 100644 index fff2c782b..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/MimeHeaderEncoderInterface.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpContentEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpContentEncoder.php deleted file mode 100644 index 4703cc2e6..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpContentEncoder.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * 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)|(? - * - * 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 $safeMapShare = []; - - /** - * A map of non-encoded ascii characters. - * - * @var string[] - * - * @internal - */ - protected $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); - } - } - - /** - * {@inheritdoc} - * - * 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); - switch ($end = \ord(substr($string, -1))) { - case 0x09: - case 0x20: - $string = substr_replace($string, self::QP_MAP[$end], -1); - } - - return $string; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpMimeHeaderEncoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpMimeHeaderEncoder.php deleted file mode 100644 index d1d38375f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/QpMimeHeaderEncoder.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Encoder/Rfc2231Encoder.php b/lam/lib/3rdParty/composer/symfony/mime/Encoder/Rfc2231Encoder.php deleted file mode 100644 index 4d93dc641..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Encoder/Rfc2231Encoder.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Exception/AddressEncoderException.php b/lam/lib/3rdParty/composer/symfony/mime/Exception/AddressEncoderException.php deleted file mode 100644 index 51ee2e06f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/AddressEncoderException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Exception/ExceptionInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Exception/ExceptionInterface.php deleted file mode 100644 index 11933900f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/ExceptionInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Exception/LogicException.php b/lam/lib/3rdParty/composer/symfony/mime/Exception/LogicException.php deleted file mode 100644 index 0508ee73c..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/LogicException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Exception/RfcComplianceException.php b/lam/lib/3rdParty/composer/symfony/mime/Exception/RfcComplianceException.php deleted file mode 100644 index 26e4a5099..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/RfcComplianceException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Exception/RuntimeException.php b/lam/lib/3rdParty/composer/symfony/mime/Exception/RuntimeException.php deleted file mode 100644 index fb018b006..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Exception/RuntimeException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/FileBinaryMimeTypeGuesser.php b/lam/lib/3rdParty/composer/symfony/mime/FileBinaryMimeTypeGuesser.php deleted file mode 100644 index 3acf4d455..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/FileBinaryMimeTypeGuesser.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * 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 $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; - } - - /** - * {@inheritdoc} - */ - 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; - } - - /** - * {@inheritdoc} - */ - 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/lam/lib/3rdParty/composer/symfony/mime/FileinfoMimeTypeGuesser.php b/lam/lib/3rdParty/composer/symfony/mime/FileinfoMimeTypeGuesser.php deleted file mode 100644 index 7964aa1cf..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/FileinfoMimeTypeGuesser.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * 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 $magicFile; - - /** - * @param string|null $magicFile A magic file to use with the finfo instance - * - * @see http://www.php.net/manual/en/function.finfo-open.php - */ - public function __construct(string $magicFile = null) - { - $this->magicFile = $magicFile; - } - - /** - * {@inheritdoc} - */ - public function isGuesserSupported(): bool - { - return \function_exists('finfo_open'); - } - - /** - * {@inheritdoc} - */ - 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/lam/lib/3rdParty/composer/symfony/mime/Header/AbstractHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/AbstractHeader.php deleted file mode 100644 index 5de906687..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/AbstractHeader.php +++ /dev/null @@ -1,284 +0,0 @@ - - * - * 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 $encoder; - - private $name; - private $lineLength = 76; - private $lang; - private $charset = 'utf-8'; - - public function __construct(string $name) - { - $this->name = $name; - } - - 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'. - */ - public function setLanguage(string $lang) - { - $this->lang = $lang; - } - - public function getLanguage(): ?string - { - return $this->lang; - } - - public function getName(): string - { - return $this->name; - } - - 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; - } - - return $tokens; - } - - /** - * Get a token as an encoded word for safe insertion into headers. - */ - protected function getTokenAsEncodedWord(string $token, int $firstLineOffset = 0): string - { - if (null === self::$encoder) { - 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 - { - if (null === $string) { - $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/lam/lib/3rdParty/composer/symfony/mime/Header/DateHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/DateHeader.php deleted file mode 100644 index a7385d4ce..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/DateHeader.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * 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 $dateTime; - - public function __construct(string $name, \DateTimeInterface $date) - { - parent::__construct($name); - - $this->setDateTime($date); - } - - /** - * @param \DateTimeInterface $body - */ - public function setBody($body) - { - $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) - { - if ($dateTime instanceof \DateTime) { - $immutable = new \DateTimeImmutable('@'.$dateTime->getTimestamp()); - $dateTime = $immutable->setTimezone($dateTime->getTimezone()); - } - $this->dateTime = $dateTime; - } - - public function getBodyAsString(): string - { - return $this->dateTime->format(\DateTime::RFC2822); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Header/HeaderInterface.php b/lam/lib/3rdParty/composer/symfony/mime/Header/HeaderInterface.php deleted file mode 100644 index 4546947c7..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/HeaderInterface.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * 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. - * - * @param mixed $body - */ - public function setBody($body); - - /** - * Gets the body. - * - * The return type depends on the Header concrete class. - * - * @return mixed - */ - public function getBody(); - - public function setCharset(string $charset); - - public function getCharset(): ?string; - - public function setLanguage(string $lang); - - public function getLanguage(): ?string; - - public function getName(): string; - - 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/lam/lib/3rdParty/composer/symfony/mime/Header/Headers.php b/lam/lib/3rdParty/composer/symfony/mime/Header/Headers.php deleted file mode 100644 index 8db912520..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/Headers.php +++ /dev/null @@ -1,307 +0,0 @@ - - * - * 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, // `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, // ... `Message-ID`, even if that is no valid `msg-id` - 'return-path' => PathHeader::class, - ]; - - /** - * @var HeaderInterface[][] - */ - private $headers = []; - private $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) - { - $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): self - { - return $this->add(new MailboxListHeader($name, Address::createArray($addresses))); - } - - /** - * @param Address|string $address - * - * @return $this - */ - public function addMailboxHeader(string $name, $address): self - { - return $this->add(new MailboxHeader($name, Address::create($address))); - } - - /** - * @param string|array $ids - * - * @return $this - */ - public function addIdHeader(string $name, $ids): self - { - return $this->add(new IdentificationHeader($name, $ids)); - } - - /** - * @param Address|string $path - * - * @return $this - */ - public function addPathHeader(string $name, $path): self - { - return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path))); - } - - /** - * @return $this - */ - public function addDateHeader(string $name, \DateTimeInterface $dateTime): self - { - return $this->add(new DateHeader($name, $dateTime)); - } - - /** - * @return $this - */ - public function addTextHeader(string $name, string $value): self - { - return $this->add(new UnstructuredHeader($name, $value)); - } - - /** - * @return $this - */ - public function addParameterizedHeader(string $name, string $value, array $params = []): self - { - return $this->add(new ParameterizedHeader($name, $value, $params)); - } - - /** - * @return $this - */ - public function addHeader(string $name, $argument, array $more = []): self - { - $parts = explode('\\', self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class); - $method = 'add'.ucfirst(array_pop($parts)); - if ('addUnstructuredHeader' === $method) { - $method = 'addTextHeader'; - } elseif ('addIdentificationHeader' === $method) { - $method = 'addIdHeader'; - } - - 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): self - { - 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()); - - if (($c = self::HEADER_CLASS_MAP[$name] ?? null) && !$header instanceof $c) { - throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $c, 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; - } - - /** - * @internal - */ - public function getHeaderBody(string $name) - { - return $this->has($name) ? $this->get($name)->getBody() : null; - } - - /** - * @internal - */ - public function setHeaderBody(string $type, string $name, $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/lam/lib/3rdParty/composer/symfony/mime/Header/IdentificationHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/IdentificationHeader.php deleted file mode 100644 index 8a94574e5..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/IdentificationHeader.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * 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 $ids = []; - private $idsAsAddresses = []; - - /** - * @param string|array $ids - */ - public function __construct(string $name, $ids) - { - parent::__construct($name); - - $this->setId($ids); - } - - /** - * @param string|array $body a string ID or an array of IDs - * - * @throws RfcComplianceException - */ - public function setBody($body) - { - $this->setId($body); - } - - public function getBody(): array - { - return $this->getIds(); - } - - /** - * Set the ID used in the value of this header. - * - * @param string|array $id - * - * @throws RfcComplianceException - */ - public function setId($id) - { - $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) - { - $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/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxHeader.php deleted file mode 100644 index b58c8252f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxHeader.php +++ /dev/null @@ -1,85 +0,0 @@ - - * - * 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; - - public function __construct(string $name, Address $address) - { - parent::__construct($name); - - $this->setAddress($address); - } - - /** - * @param Address $body - * - * @throws RfcComplianceException - */ - public function setBody($body) - { - $this->setAddress($body); - } - - /** - * @throws RfcComplianceException - */ - public function getBody(): Address - { - return $this->getAddress(); - } - - /** - * @throws RfcComplianceException - */ - public function setAddress(Address $address) - { - $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/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxListHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxListHeader.php deleted file mode 100644 index ee2a26cf2..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/MailboxListHeader.php +++ /dev/null @@ -1,136 +0,0 @@ - - * - * 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 $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($body) - { - $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) - { - $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) - { - foreach ($addresses as $address) { - $this->addAddress($address); - } - } - - /** - * @throws RfcComplianceException - */ - public function addAddress(Address $address) - { - $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/lam/lib/3rdParty/composer/symfony/mime/Header/ParameterizedHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/ParameterizedHeader.php deleted file mode 100644 index e5d4238b4..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/ParameterizedHeader.php +++ /dev/null @@ -1,191 +0,0 @@ - - * - * 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 $encoder; - private $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) - { - $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) - { - $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/lam/lib/3rdParty/composer/symfony/mime/Header/PathHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/PathHeader.php deleted file mode 100644 index 5101ad0f9..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/PathHeader.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * 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; - - public function __construct(string $name, Address $address) - { - parent::__construct($name); - - $this->setAddress($address); - } - - /** - * @param Address $body - * - * @throws RfcComplianceException - */ - public function setBody($body) - { - $this->setAddress($body); - } - - public function getBody(): Address - { - return $this->getAddress(); - } - - public function setAddress(Address $address) - { - $this->address = $address; - } - - public function getAddress(): Address - { - return $this->address; - } - - public function getBodyAsString(): string - { - return '<'.$this->address->toString().'>'; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Header/UnstructuredHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Header/UnstructuredHeader.php deleted file mode 100644 index 2085ddfde..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Header/UnstructuredHeader.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * 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 $value; - - public function __construct(string $name, string $value) - { - parent::__construct($name); - - $this->setValue($value); - } - - /** - * @param string $body - */ - public function setBody($body) - { - $this->setValue($body); - } - - /** - * @return string - */ - public function getBody() - { - return $this->getValue(); - } - - /** - * Get the (unencoded) value of this header. - */ - public function getValue(): string - { - return $this->value; - } - - /** - * Set the (unencoded) value of this header. - */ - 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/lam/lib/3rdParty/composer/symfony/mime/Message.php b/lam/lib/3rdParty/composer/symfony/mime/Message.php deleted file mode 100644 index 651ffd452..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Message.php +++ /dev/null @@ -1,160 +0,0 @@ - - * - * 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; - private $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) - { - $this->body = $body; - - return $this; - } - - public function getBody(): ?AbstractPart - { - return $this->body; - } - - /** - * @return $this - */ - public function setHeaders(Headers $headers) - { - $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(); - } - - public function ensureValidity() - { - if (!$this->headers->has('To') && !$this->headers->has('Cc') && !$this->headers->has('Bcc')) { - throw new LogicException('An email must have a "To", "Cc", or "Bcc" header.'); - } - - if (!$this->headers->has('From') && !$this->headers->has('Sender')) { - 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')) { - $sender = $this->headers->get('From')->getAddresses()[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/lam/lib/3rdParty/composer/symfony/mime/MessageConverter.php b/lam/lib/3rdParty/composer/symfony/mime/MessageConverter.php deleted file mode 100644 index 0539eac8e..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/MessageConverter.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * 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::attachParts($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::attachParts($email, \array_slice($parts, 1)); - } - - private static function attachParts(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))); - } - - $headers = $part->getPreparedHeaders(); - $method = 'inline' === $headers->getHeaderBody('Content-Disposition') ? 'embed' : 'attach'; - $name = $headers->getHeaderParameter('Content-Disposition', 'filename'); - $email->$method($part->getBody(), $name, $part->getMediaType().'/'.$part->getMediaSubtype()); - } - - return $email; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/MimeTypeGuesserInterface.php b/lam/lib/3rdParty/composer/symfony/mime/MimeTypeGuesserInterface.php deleted file mode 100644 index 30ee3b64a..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/MimeTypeGuesserInterface.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/MimeTypes.php b/lam/lib/3rdParty/composer/symfony/mime/MimeTypes.php deleted file mode 100644 index bdea994b5..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/MimeTypes.php +++ /dev/null @@ -1,3537 +0,0 @@ - - * - * 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 $extensions = []; - private $mimeTypes = []; - - /** - * @var MimeTypeGuesserInterface[] - */ - private $guessers = []; - private static $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) - { - self::$default = $default; - } - - public static function getDefault(): self - { - return self::$default ?? self::$default = new self(); - } - - /** - * Registers a MIME type guesser. - * - * The last registered guesser has precedence over the other ones. - */ - public function registerGuesser(MimeTypeGuesserInterface $guesser) - { - array_unshift($this->guessers, $guesser); - } - - /** - * {@inheritdoc} - */ - 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)] ?? []; - } - - /** - * {@inheritdoc} - */ - 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)] ?? []; - } - - /** - * {@inheritdoc} - */ - public function isGuesserSupported(): bool - { - foreach ($this->guessers as $guesser) { - if ($guesser->isGuesserSupported()) { - return true; - } - } - - return false; - } - - /** - * {@inheritdoc} - * - * 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 2021-09-03 - * - * @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/bdoc' => ['bdoc'], - 'application/bzip2' => ['bz2', 'bz'], - 'application/calendar+xml' => ['xcs'], - '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/csv' => ['csv'], - 'application/cu-seeme' => ['cu'], - 'application/dash+xml' => ['mpd'], - '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/fdt+xml' => ['fdt'], - '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/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' => ['skr', 'pkr', 'asc', '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'], - '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.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.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.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-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.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/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-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-bcpio' => ['bcpio'], - 'application/x-bdoc' => ['bdoc'], - 'application/x-bittorrent' => ['torrent'], - 'application/x-blender' => ['blender', 'blend', 'BLEND'], - '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', 'bz2'], - 'application/x-bzip-compressed-tar' => ['tar.bz2', 'tar.bz', 'tbz2', 'tbz', 'tb2'], - 'application/x-bzip2' => ['bz2', 'boz', 'bz'], - '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-eva' => ['eva'], - 'application/x-fd-file' => ['fd', 'qd'], - 'application/x-fds-disk' => ['fds'], - 'application/x-fictionbook' => ['fb2'], - 'application/x-fictionbook+xml' => ['fb2'], - '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-gedcom' => ['ged', 'gedcom'], - 'application/x-genesis-32x-rom' => ['32x', 'mdx'], - 'application/x-genesis-rom' => ['gen', 'smd', 'sgd'], - '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-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-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-ms-application' => ['application'], - 'application/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'], - 'application/x-ms-dos-executable' => ['exe'], - '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-nzb' => ['nzb'], - 'application/x-object' => ['o', 'mod'], - 'application/x-ogg' => ['ogx'], - 'application/x-oleo' => ['oleo'], - '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-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-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'], - 'application/x-zip-compressed' => ['zip'], - 'application/x-zip-compressed-fb2' => ['fb2.zip'], - 'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], - 'application/x-zoo' => ['zoo'], - '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/yang' => ['yang'], - 'application/yin+xml' => ['yin'], - 'application/zip' => ['zip'], - '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/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', 'xmf'], - '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.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.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-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-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'], - 'image/astc' => ['astc'], - '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'], - 'image/g3fax' => ['g3'], - 'image/gif' => ['gif'], - 'image/heic' => ['heic', 'heif'], - 'image/heic-sequence' => ['heics', 'heic', 'heif'], - 'image/heif' => ['heif', 'heic'], - 'image/heif-sequence' => ['heifs', 'heic', 'heif'], - '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'], - '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/rle' => ['rle'], - 'image/sgi' => ['sgi'], - 'image/svg' => ['svg'], - 'image/svg+xml' => ['svg', 'svgz'], - 'image/svg+xml-compressed' => ['svgz'], - '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.ms-dds' => ['dds'], - 'image/vnd.ms-modi' => ['mdi'], - 'image/vnd.ms-photo' => ['wdp'], - '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'], - '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+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/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.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-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-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-fortran' => ['f', 'for', 'f77', 'f90', 'f95'], - '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-mpsub' => ['sub'], - 'text/x-mrml' => ['mrml', 'mrl'], - 'text/x-ms-regedit' => ['reg'], - 'text/x-mup' => ['mup', 'not'], - 'text/x-nfo' => ['nfo'], - '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-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.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/webm' => ['webm'], - 'video/x-anim' => ['anim[1-9j]'], - '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 = [ - '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' => ['model/3mf'], - '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'], - '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'], - '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'], - 'anim[1-9j]' => ['video/x-anim'], - 'anx' => ['application/annodex', 'application/x-annodex'], - 'ape' => ['audio/x-ape'], - 'apk' => ['application/vnd.android.package-archive'], - 'apng' => ['image/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'], - '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'], - 'avf' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], - 'avi' => ['video/avi', 'video/divx', 'video/msvideo', '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/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'], - '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', 'application/x-bzip2'], - 'bz2' => ['application/x-bz2', 'application/bzip2', 'application/x-bzip', 'application/x-bzip2'], - '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'], - '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'], - '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'], - '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.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'], - 'drle' => ['image/dicom-rle'], - 'dsc' => ['text/prs.lines.tag'], - 'dsl' => ['text/x-dsl'], - 'dssc' => ['application/dssc+der'], - 'dtb' => ['application/x-dtbook+xml'], - 'dtd' => ['application/xml-dtd', 'text/x-dtd'], - 'dts' => ['audio/vnd.dts', 'audio/x-dts'], - 'dtshd' => ['audio/vnd.dts.hd', 'audio/x-dtshd'], - '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'], - 'erl' => ['text/x-erlang'], - 'es' => ['application/ecmascript', 'text/ecmascript'], - 'es3' => ['application/vnd.eszigno3+xml'], - 'esa' => ['application/vnd.osgi.subsystem'], - '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'], - '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'], - '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'], - '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', 'image/x-gimp-gbr'], - 'gca' => ['application/x-gca-compressed'], - 'gcode' => ['text/x.gcode'], - 'gcrd' => ['text/directory', 'text/vcard', 'text/x-vcard'], - 'gdi' => ['application/x-gd-rom-cue'], - 'gdl' => ['model/vnd.gdl'], - 'gdoc' => ['application/vnd.google-apps.document'], - 'ged' => ['application/x-gedcom', 'text/gedcom'], - 'gedcom' => ['application/x-gedcom', 'text/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'], - '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'], - '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'], - '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/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/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/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'], - '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'], - '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'], - '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-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-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'], - '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' => ['video/mp2t'], - 'mpls' => ['video/mp2t'], - 'mpm' => ['application/vnd.blueice.multipass'], - 'mpn' => ['application/vnd.mophun.application'], - 'mpp' => ['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'], - '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'], - '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'], - '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'], - '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'], - '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'], - '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-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'], - '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'], - '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'], - 'qp' => ['application/x-qpress'], - 'qps' => ['application/vnd.publishare-delta-tree'], - '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/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'], - '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'], - '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-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'], - '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'], - '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'], - '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-bzip-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-bzip-compressed-tar'], - 'tbz' => ['application/x-bzip-compressed-tar'], - 'tbz2' => ['application/x-bzip-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'], - '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'], - 'trig' => ['application/trig', 'application/x-trig'], - 'trm' => ['application/x-msterminal'], - 'ts' => ['application/x-linguist', 'text/vnd.qt.linguist', 'text/vnd.trolltech.linguist', 'video/mp2t'], - 'tsd' => ['application/timestamped-data'], - 'tsv' => ['text/tab-separated-values'], - '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'], - '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/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'], - '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/mobile-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/x-yaml', 'text/x-yaml', 'text/yaml'], - 'yang' => ['application/yang'], - 'yin' => ['application/yin+xml'], - 'yml' => ['application/x-yaml', 'text/x-yaml', 'text/yaml'], - 'ymp' => ['text/x-suse-ymp'], - 'yt' => ['application/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'], - 'zip' => ['application/zip', 'application/x-zip', 'application/x-zip-compressed'], - 'zir' => ['application/vnd.zul'], - 'zirz' => ['application/vnd.zul'], - 'zmm' => ['application/vnd.handheld-entertainment+xml'], - 'zoo' => ['application/x-zoo'], - 'zsav' => ['application/x-spss-sav', 'application/x-spss-savefile'], - 'zst' => ['application/zstd'], - 'zz' => ['application/zlib'], - '123' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], - '602' => ['application/x-t602'], - '669' => ['audio/x-mod'], - ]; -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/MimeTypesInterface.php b/lam/lib/3rdParty/composer/symfony/mime/MimeTypesInterface.php deleted file mode 100644 index 17d45ad21..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/MimeTypesInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractMultipartPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractMultipartPart.php deleted file mode 100644 index 685d25062..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractMultipartPart.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * 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 $boundary; - private $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 - { - if (null === $this->boundary) { - $this->boundary = strtr(base64_encode(random_bytes(6)), '+/', '-_'); - } - - return $this->boundary; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractPart.php deleted file mode 100644 index 93892d9df..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/AbstractPart.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * 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; - - 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/lam/lib/3rdParty/composer/symfony/mime/Part/DataPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/DataPart.php deleted file mode 100644 index 4247ce798..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/DataPart.php +++ /dev/null @@ -1,183 +0,0 @@ - - * - * 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; -use Symfony\Component\Mime\MimeTypes; - -/** - * @author Fabien Potencier - */ -class DataPart extends TextPart -{ - /** @internal */ - protected $_parent; - - private static $mimeTypes; - - private $filename; - private $mediaType; - private $cid; - private $handle; - - /** - * @param resource|string $body - */ - public function __construct($body, string $filename = null, string $contentType = null, string $encoding = null) - { - unset($this->_parent); - - if (null === $contentType) { - $contentType = '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 - { - if (null === $contentType) { - $ext = strtolower(substr($path, strrpos($path, '.') + 1)); - if (null === self::$mimeTypes) { - self::$mimeTypes = new MimeTypes(); - } - $contentType = self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream'; - } - - if ((is_file($path) && !is_readable($path)) || is_dir($path)) { - throw new InvalidArgumentException(sprintf('Path "%s" is not readable.', $path)); - } - - if (false === $handle = @fopen($path, 'r', false)) { - throw new InvalidArgumentException(sprintf('Unable to open path "%s".', $path)); - } - - if (!is_file($path)) { - $cache = fopen('php://temp', 'r+'); - stream_copy_to_stream($handle, $cache); - $handle = $cache; - } - - $p = new self($handle, $name ?: basename($path), $contentType); - $p->handle = $handle; - - return $p; - } - - /** - * @return $this - */ - public function asInline() - { - return $this->setDisposition('inline'); - } - - 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; - } - - private function generateContentId(): string - { - return bin2hex(random_bytes(16)).'@symfony'; - } - - public function __destruct() - { - if (null !== $this->handle && \is_resource($this->handle)) { - fclose($this->handle); - } - } - - /** - * @return array - */ - public function __sleep() - { - // 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); - $r->setAccessible(true); - $this->_parent[$name] = $r->getValue($this); - } - $this->_headers = $this->getHeaders(); - - return ['_headers', '_parent', 'filename', 'mediaType']; - } - - public function __wakeup() - { - $r = new \ReflectionProperty(AbstractPart::class, 'headers'); - $r->setAccessible(true); - $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])) { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - $r = new \ReflectionProperty(TextPart::class, $name); - $r->setAccessible(true); - $r->setValue($this, $this->_parent[$name]); - } - unset($this->_parent); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Part/MessagePart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/MessagePart.php deleted file mode 100644 index 00129b475..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/MessagePart.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * 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 $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(); - } - - /** - * @return array - */ - public function __sleep() - { - return ['message']; - } - - public function __wakeup() - { - $this->__construct($this->message); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/AlternativePart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/AlternativePart.php deleted file mode 100644 index fd7542347..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/AlternativePart.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/DigestPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/DigestPart.php deleted file mode 100644 index 27537f15b..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/DigestPart.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/FormDataPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/FormDataPart.php deleted file mode 100644 index e3c9afc04..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/FormDataPart.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * 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\DataPart; -use Symfony\Component\Mime\Part\TextPart; - -/** - * Implements RFC 7578. - * - * @author Fabien Potencier - */ -final class FormDataPart extends AbstractMultipartPart -{ - private $fields = []; - - /** - * @param array $fields - */ - public function __construct(array $fields = []) - { - parent::__construct(); - - foreach ($fields as $name => $value) { - if (!\is_string($value) && !\is_array($value) && !$value instanceof TextPart) { - throw new InvalidArgumentException(sprintf('A form field value can only be a string, an array, or an instance of TextPart ("%s" given).', get_debug_type($value))); - } - - $this->fields[$name] = $value; - } - // 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; - } - - $values[] = $this->preparePart($fieldName, $item); - }; - - array_walk($fields, $prepare); - - return $values; - } - - private function preparePart(string $name, $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; - - if (null === $r) { - $r = new \ReflectionProperty(TextPart::class, 'encoding'); - $r->setAccessible(true); - } - - $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/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/MixedPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/MixedPart.php deleted file mode 100644 index c8d7028cd..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/MixedPart.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * 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/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/RelatedPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/RelatedPart.php deleted file mode 100644 index 08fdd5fa9..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/Multipart/RelatedPart.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * 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 $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/lam/lib/3rdParty/composer/symfony/mime/Part/SMimePart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/SMimePart.php deleted file mode 100644 index cb619c293..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/SMimePart.php +++ /dev/null @@ -1,121 +0,0 @@ - - * - * 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; - - private $body; - private $type; - private $subtype; - private $parameters; - - /** - * @param iterable|string $body - */ - public function __construct($body, string $type, string $subtype, array $parameters) - { - unset($this->_headers); - - parent::__construct(); - - if (!\is_string($body) && !is_iterable($body)) { - throw new \TypeError(sprintf('The body of "%s" must be a string or a iterable (got "%s").', self::class, get_debug_type($body))); - } - - $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->setAccessible(true); - $r->setValue($this, $this->_headers); - unset($this->_headers); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Part/TextPart.php b/lam/lib/3rdParty/composer/symfony/mime/Part/TextPart.php deleted file mode 100644 index bfe41c0aa..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Part/TextPart.php +++ /dev/null @@ -1,215 +0,0 @@ - - * - * 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; - - private static $encoders = []; - - private $body; - private $charset; - private $subtype; - /** - * @var ?string - */ - private $disposition; - private $name; - private $encoding; - private $seekable; - - /** - * @param resource|string $body - */ - public function __construct($body, ?string $charset = 'utf-8', string $subtype = 'plain', string $encoding = null) - { - unset($this->_headers); - - parent::__construct(); - - if (!\is_string($body) && !\is_resource($body)) { - throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, get_debug_type($body))); - } - - $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) - { - $this->disposition = $disposition; - - return $this; - } - - /** - * Sets the name of the file (used by FormDataPart). - * - * @return $this - */ - public function setName(string $name) - { - $this->name = $name; - - return $this; - } - - public function getBody(): string - { - 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 (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] ?? (self::$encoders[$this->encoding] = new EightBitContentEncoder()); - } - - if ('quoted-printable' === $this->encoding) { - return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new QpContentEncoder()); - } - - return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new Base64ContentEncoder()); - } - - private function chooseEncoding(): string - { - if (null === $this->charset) { - return 'base64'; - } - - return 'quoted-printable'; - } - - /** - * @return array - */ - public function __sleep() - { - // 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']; - } - - public function __wakeup() - { - $r = new \ReflectionProperty(AbstractPart::class, 'headers'); - $r->setAccessible(true); - $r->setValue($this, $this->_headers); - unset($this->_headers); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/README.md b/lam/lib/3rdParty/composer/symfony/mime/README.md deleted file mode 100644 index 8e4d5c77f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/README.md +++ /dev/null @@ -1,13 +0,0 @@ -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/lam/lib/3rdParty/composer/symfony/mime/RawMessage.php b/lam/lib/3rdParty/composer/symfony/mime/RawMessage.php deleted file mode 100644 index d2a311dae..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/RawMessage.php +++ /dev/null @@ -1,91 +0,0 @@ - - * - * 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 implements \Serializable -{ - private $message; - - /** - * @param iterable|string $message - */ - public function __construct($message) - { - $this->message = $message; - } - - public function toString(): string - { - if (\is_string($this->message)) { - return $this->message; - } - if ($this->message instanceof \Traversable) { - $this->message = iterator_to_array($this->message, false); - } - - return $this->message = implode('', $this->message); - } - - public function toIterable(): iterable - { - if (\is_string($this->message)) { - yield $this->message; - - return; - } - - $message = ''; - foreach ($this->message as $chunk) { - $message .= $chunk; - yield $chunk; - } - $this->message = $message; - } - - /** - * @throws LogicException if the message is not valid - */ - public function ensureValidity() - { - } - - /** - * @internal - */ - final public function serialize(): string - { - return serialize($this->__serialize()); - } - - /** - * @internal - */ - final public function unserialize($serialized) - { - $this->__unserialize(unserialize($serialized)); - } - - public function __serialize(): array - { - return [$this->toString()]; - } - - public function __unserialize(array $data): void - { - [$this->message] = $data; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Resources/bin/update_mime_types.php b/lam/lib/3rdParty/composer/symfony/mime/Resources/bin/update_mime_types.php deleted file mode 100644 index 5586f097f..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Resources/bin/update_mime_types.php +++ /dev/null @@ -1,165 +0,0 @@ - - * - * 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@v1.49.0/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'], - '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'], - '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 .+?\.}', 'Updated from upstream on '.date('Y-m-d'), $updated, -1); - -file_put_contents($output, rtrim($updated, "\n")."\n"); - -echo "Done.\n"; diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAddressContains.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAddressContains.php deleted file mode 100644 index 827e14147..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAddressContains.php +++ /dev/null @@ -1,74 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\Header\MailboxHeader; -use Symfony\Component\Mime\Header\MailboxListHeader; -use Symfony\Component\Mime\RawMessage; - -final class EmailAddressContains extends Constraint -{ - private $headerName; - private $expectedValue; - - public function __construct(string $headerName, string $expectedValue) - { - $this->headerName = $headerName; - $this->expectedValue = $expectedValue; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('contains address "%s" with value "%s"', $this->headerName, $this->expectedValue); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message)) { - throw new \LogicException('Unable to test a message address on a RawMessage instance.'); - } - - $header = $message->getHeaders()->get($this->headerName); - if ($header instanceof MailboxHeader) { - return $this->expectedValue === $header->getAddress()->getAddress(); - } elseif ($header instanceof MailboxListHeader) { - foreach ($header->getAddresses() as $address) { - if ($this->expectedValue === $address->getAddress()) { - return true; - } - } - - return false; - } - - throw new \LogicException('Unable to test a message address on a non-address header.'); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function failureDescription($message): string - { - return sprintf('the Email %s (value is %s)', $this->toString(), $message->getHeaders()->get($this->headerName)->getBodyAsString()); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAttachmentCount.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAttachmentCount.php deleted file mode 100644 index c0adbe3a0..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailAttachmentCount.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\Message; -use Symfony\Component\Mime\RawMessage; - -final class EmailAttachmentCount extends Constraint -{ - private $expectedValue; - private $transport; - - public function __construct(int $expectedValue, string $transport = null) - { - $this->expectedValue = $expectedValue; - $this->transport = $transport; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('has sent "%d" attachment(s)', $this->expectedValue); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) { - throw new \LogicException('Unable to test a message attachment on a RawMessage or Message instance.'); - } - - return $this->expectedValue === \count($message->getAttachments()); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function failureDescription($message): string - { - return 'the Email '.$this->toString(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHasHeader.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHasHeader.php deleted file mode 100644 index a29f835fc..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHasHeader.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. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\RawMessage; - -final class EmailHasHeader extends Constraint -{ - private $headerName; - - public function __construct(string $headerName) - { - $this->headerName = $headerName; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('has header "%s"', $this->headerName); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message)) { - throw new \LogicException('Unable to test a message header on a RawMessage instance.'); - } - - return $message->getHeaders()->has($this->headerName); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function failureDescription($message): string - { - return 'the Email '.$this->toString(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHeaderSame.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHeaderSame.php deleted file mode 100644 index 74b412183..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHeaderSame.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\Header\UnstructuredHeader; -use Symfony\Component\Mime\RawMessage; - -final class EmailHeaderSame extends Constraint -{ - private $headerName; - private $expectedValue; - - public function __construct(string $headerName, string $expectedValue) - { - $this->headerName = $headerName; - $this->expectedValue = $expectedValue; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('has header "%s" with value "%s"', $this->headerName, $this->expectedValue); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message)) { - throw new \LogicException('Unable to test a message header on a RawMessage instance.'); - } - - return $this->expectedValue === $this->getHeaderValue($message); - } - - /** - * @param RawMessage $message - * - * {@inheritdoc} - */ - protected function failureDescription($message): string - { - return sprintf('the Email %s (value is %s)', $this->toString(), $this->getHeaderValue($message) ?? 'null'); - } - - private function getHeaderValue($message): ?string - { - if (null === $header = $message->getHeaders()->get($this->headerName)) { - return null; - } - - return $header instanceof UnstructuredHeader ? $header->getValue() : $header->getBodyAsString(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php deleted file mode 100644 index 3c61376e1..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\Message; -use Symfony\Component\Mime\RawMessage; - -final class EmailHtmlBodyContains extends Constraint -{ - private $expectedText; - - public function __construct(string $expectedText) - { - $this->expectedText = $expectedText; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('contains "%s"', $this->expectedText); - } - - /** - * {@inheritdoc} - * - * @param RawMessage $message - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) { - throw new \LogicException('Unable to test a message HTML body on a RawMessage or Message instance.'); - } - - return false !== mb_strpos($message->getHtmlBody(), $this->expectedText); - } - - /** - * {@inheritdoc} - * - * @param RawMessage $message - */ - protected function failureDescription($message): string - { - return 'the Email HTML body '.$this->toString(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailTextBodyContains.php b/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailTextBodyContains.php deleted file mode 100644 index 063d96306..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/Test/Constraint/EmailTextBodyContains.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Mime\Test\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Mime\Message; -use Symfony\Component\Mime\RawMessage; - -final class EmailTextBodyContains extends Constraint -{ - private $expectedText; - - public function __construct(string $expectedText) - { - $this->expectedText = $expectedText; - } - - /** - * {@inheritdoc} - */ - public function toString(): string - { - return sprintf('contains "%s"', $this->expectedText); - } - - /** - * {@inheritdoc} - * - * @param RawMessage $message - */ - protected function matches($message): bool - { - if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) { - throw new \LogicException('Unable to test a message text body on a RawMessage or Message instance.'); - } - - return false !== mb_strpos($message->getTextBody(), $this->expectedText); - } - - /** - * {@inheritdoc} - * - * @param RawMessage $message - */ - protected function failureDescription($message): string - { - return 'the Email text body '.$this->toString(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/mime/composer.json b/lam/lib/3rdParty/composer/symfony/mime/composer.json deleted file mode 100644 index 195f041a4..000000000 --- a/lam/lib/3rdParty/composer/symfony/mime/composer.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "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": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.4.26|~6.2.13|^6.3.2" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4", - "symfony/serializer": "<5.4.26|>=6,<6.2.13|>=6.3,<6.3.2" - }, - "autoload": { - "psr-4": { "Symfony\\Component\\Mime\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "minimum-stability": "dev" -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/Ctype.php b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/Ctype.php deleted file mode 100644 index ba75a2c95..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/Ctype.php +++ /dev/null @@ -1,232 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Ctype; - -/** - * Ctype implementation through regex. - * - * @internal - * - * @author Gert de Pagter - */ -final class Ctype -{ - /** - * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. - * - * @see https://php.net/ctype-alnum - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alnum($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is a letter, FALSE otherwise. - * - * @see https://php.net/ctype-alpha - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alpha($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); - } - - /** - * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. - * - * @see https://php.net/ctype-cntrl - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_cntrl($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); - } - - /** - * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. - * - * @see https://php.net/ctype-digit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_digit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. - * - * @see https://php.net/ctype-graph - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_graph($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); - } - - /** - * Returns TRUE if every character in text is a lowercase letter. - * - * @see https://php.net/ctype-lower - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_lower($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); - } - - /** - * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. - * - * @see https://php.net/ctype-print - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_print($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); - } - - /** - * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. - * - * @see https://php.net/ctype-punct - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_punct($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); - } - - /** - * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. - * - * @see https://php.net/ctype-space - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_space($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); - } - - /** - * Returns TRUE if every character in text is an uppercase letter. - * - * @see https://php.net/ctype-upper - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_upper($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); - } - - /** - * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. - * - * @see https://php.net/ctype-xdigit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_xdigit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); - } - - /** - * Converts integers to their char versions according to normal ctype behaviour, if needed. - * - * If an integer between -128 and 255 inclusive is provided, - * it is interpreted as the ASCII value of a single character - * (negative values have 256 added in order to allow characters in the Extended ASCII range). - * Any other integer is interpreted as a string containing the decimal digits of the integer. - * - * @param mixed $int - * @param string $function - * - * @return mixed - */ - private static function convert_int_to_char_for_ctype($int, $function) - { - if (!\is_int($int)) { - return $int; - } - - if ($int < -128 || $int > 255) { - return (string) $int; - } - - if (\PHP_VERSION_ID >= 80100) { - @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); - } - - if ($int < 0) { - $int += 256; - } - - return \chr($int); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/LICENSE b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/LICENSE deleted file mode 100644 index 7536caeae..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2018-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/lam/lib/3rdParty/composer/symfony/polyfill-ctype/README.md b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/README.md deleted file mode 100644 index b144d03c3..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / Ctype -======================== - -This component provides `ctype_*` functions to users who run php versions without the ctype extension. - -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/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap.php b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap.php deleted file mode 100644 index d54524b31..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('ctype_alnum')) { - function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit($text) { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph($text) { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower($text) { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print($text) { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct($text) { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space($text) { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper($text) { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap80.php b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap80.php deleted file mode 100644 index ab2f8611d..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/bootstrap80.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (!function_exists('ctype_alnum')) { - function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/composer.json b/lam/lib/3rdParty/composer/symfony/polyfill-ctype/composer.json deleted file mode 100644 index e5c978f15..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-ctype/composer.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "symfony/polyfill-ctype", - "type": "library", - "description": "Symfony polyfill for ctype functions", - "keywords": ["polyfill", "compatibility", "portable", "ctype"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, - "files": [ "bootstrap.php" ] - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Idn.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Idn.php deleted file mode 100644 index 3dc061209..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Idn.php +++ /dev/null @@ -1,923 +0,0 @@ - and Trevor Rowbotham - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Idn; - -use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges; -use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex; - -/** - * @see https://www.unicode.org/reports/tr46/ - * - * @internal - */ -final class Idn -{ - public const ERROR_EMPTY_LABEL = 1; - public const ERROR_LABEL_TOO_LONG = 2; - public const ERROR_DOMAIN_NAME_TOO_LONG = 4; - public const ERROR_LEADING_HYPHEN = 8; - public const ERROR_TRAILING_HYPHEN = 0x10; - public const ERROR_HYPHEN_3_4 = 0x20; - public const ERROR_LEADING_COMBINING_MARK = 0x40; - public const ERROR_DISALLOWED = 0x80; - public const ERROR_PUNYCODE = 0x100; - public const ERROR_LABEL_HAS_DOT = 0x200; - public const ERROR_INVALID_ACE_LABEL = 0x400; - public const ERROR_BIDI = 0x800; - public const ERROR_CONTEXTJ = 0x1000; - public const ERROR_CONTEXTO_PUNCTUATION = 0x2000; - public const ERROR_CONTEXTO_DIGITS = 0x4000; - - public const INTL_IDNA_VARIANT_2003 = 0; - public const INTL_IDNA_VARIANT_UTS46 = 1; - - public const IDNA_DEFAULT = 0; - public const IDNA_ALLOW_UNASSIGNED = 1; - public const IDNA_USE_STD3_RULES = 2; - public const IDNA_CHECK_BIDI = 4; - public const IDNA_CHECK_CONTEXTJ = 8; - public const IDNA_NONTRANSITIONAL_TO_ASCII = 16; - public const IDNA_NONTRANSITIONAL_TO_UNICODE = 32; - - public const MAX_DOMAIN_SIZE = 253; - public const MAX_LABEL_SIZE = 63; - - public const BASE = 36; - public const TMIN = 1; - public const TMAX = 26; - public const SKEW = 38; - public const DAMP = 700; - public const INITIAL_BIAS = 72; - public const INITIAL_N = 128; - public const DELIMITER = '-'; - public const MAX_INT = 2147483647; - - /** - * Contains the numeric value of a basic code point (for use in representing integers) in the - * range 0 to BASE-1, or -1 if b is does not represent a value. - * - * @var array - */ - private static $basicToDigit = [ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, - - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - ]; - - /** - * @var array - */ - private static $virama; - - /** - * @var array - */ - private static $mapped; - - /** - * @var array - */ - private static $ignored; - - /** - * @var array - */ - private static $deviation; - - /** - * @var array - */ - private static $disallowed; - - /** - * @var array - */ - private static $disallowed_STD3_mapped; - - /** - * @var array - */ - private static $disallowed_STD3_valid; - - /** - * @var bool - */ - private static $mappingTableLoaded = false; - - /** - * @see https://www.unicode.org/reports/tr46/#ToASCII - * - * @param string $domainName - * @param int $options - * @param int $variant - * @param array $idna_info - * - * @return string|false - */ - 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) { - @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); - } - - $options = [ - 'CheckHyphens' => true, - 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), - 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), - 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), - 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII), - 'VerifyDnsLength' => true, - ]; - $info = new Info(); - $labels = self::process((string) $domainName, $options, $info); - - foreach ($labels as $i => $label) { - // Only convert labels to punycode that contain non-ASCII code points - if (1 === preg_match('/[^\x00-\x7F]/', $label)) { - try { - $label = 'xn--'.self::punycodeEncode($label); - } catch (\Exception $e) { - $info->errors |= self::ERROR_PUNYCODE; - } - - $labels[$i] = $label; - } - } - - if ($options['VerifyDnsLength']) { - self::validateDomainAndLabelLength($labels, $info); - } - - $idna_info = [ - 'result' => implode('.', $labels), - 'isTransitionalDifferent' => $info->transitionalDifferent, - 'errors' => $info->errors, - ]; - - return 0 === $info->errors ? $idna_info['result'] : false; - } - - /** - * @see https://www.unicode.org/reports/tr46/#ToUnicode - * - * @param string $domainName - * @param int $options - * @param int $variant - * @param array $idna_info - * - * @return string|false - */ - 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) { - @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); - } - - $info = new Info(); - $labels = self::process((string) $domainName, [ - 'CheckHyphens' => true, - 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), - 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), - 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), - 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_UNICODE), - ], $info); - $idna_info = [ - 'result' => implode('.', $labels), - 'isTransitionalDifferent' => $info->transitionalDifferent, - 'errors' => $info->errors, - ]; - - return 0 === $info->errors ? $idna_info['result'] : false; - } - - /** - * @param string $label - * - * @return bool - */ - private static function isValidContextJ(array $codePoints, $label) - { - if (!isset(self::$virama)) { - self::$virama = require __DIR__.\DIRECTORY_SEPARATOR.'Resources'.\DIRECTORY_SEPARATOR.'unidata'.\DIRECTORY_SEPARATOR.'virama.php'; - } - - $offset = 0; - - foreach ($codePoints as $i => $codePoint) { - if (0x200C !== $codePoint && 0x200D !== $codePoint) { - continue; - } - - if (!isset($codePoints[$i - 1])) { - return false; - } - - // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; - if (isset(self::$virama[$codePoints[$i - 1]])) { - continue; - } - - // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then - // True; - // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}] - if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, \PREG_OFFSET_CAPTURE, $offset)) { - $offset += \strlen($matches[1][0]); - - continue; - } - - return false; - } - - return true; - } - - /** - * @see https://www.unicode.org/reports/tr46/#ProcessingStepMap - * - * @param string $input - * @param array $options - * - * @return string - */ - private static function mapCodePoints($input, array $options, Info $info) - { - $str = ''; - $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; - $transitional = $options['Transitional_Processing']; - - foreach (self::utf8Decode($input) as $codePoint) { - $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); - - switch ($data['status']) { - case 'disallowed': - $info->errors |= self::ERROR_DISALLOWED; - - // no break. - - case 'valid': - $str .= mb_chr($codePoint, 'utf-8'); - - break; - - case 'ignored': - // Do nothing. - break; - - case 'mapped': - $str .= $data['mapping']; - - break; - - case 'deviation': - $info->transitionalDifferent = true; - $str .= ($transitional ? $data['mapping'] : mb_chr($codePoint, 'utf-8')); - - break; - } - } - - return $str; - } - - /** - * @see https://www.unicode.org/reports/tr46/#Processing - * - * @param string $domain - * @param array $options - * - * @return array - */ - private static function process($domain, array $options, Info $info) - { - // If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and - // we need to respect the VerifyDnsLength option. - $checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength']; - - if ($checkForEmptyLabels && '' === $domain) { - $info->errors |= self::ERROR_EMPTY_LABEL; - - return [$domain]; - } - - // Step 1. Map each code point in the domain name string - $domain = self::mapCodePoints($domain, $options, $info); - - // Step 2. Normalize the domain name string to Unicode Normalization Form C. - if (!\Normalizer::isNormalized($domain, \Normalizer::FORM_C)) { - $domain = \Normalizer::normalize($domain, \Normalizer::FORM_C); - } - - // Step 3. Break the string into labels at U+002E (.) FULL STOP. - $labels = explode('.', $domain); - $lastLabelIndex = \count($labels) - 1; - - // Step 4. Convert and validate each label in the domain name string. - foreach ($labels as $i => $label) { - $validationOptions = $options; - - if ('xn--' === substr($label, 0, 4)) { - try { - $label = self::punycodeDecode(substr($label, 4)); - } catch (\Exception $e) { - $info->errors |= self::ERROR_PUNYCODE; - - continue; - } - - $validationOptions['Transitional_Processing'] = false; - $labels[$i] = $label; - } - - self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex); - } - - if ($info->bidiDomain && !$info->validBidiDomain) { - $info->errors |= self::ERROR_BIDI; - } - - // Any input domain name string that does not record an error has been successfully - // processed according to this specification. Conversely, if an input domain_name string - // causes an error, then the processing of the input domain_name string fails. Determining - // what to do with error input is up to the caller, and not in the scope of this document. - return $labels; - } - - /** - * @see https://tools.ietf.org/html/rfc5893#section-2 - * - * @param string $label - */ - private static function validateBidiLabel($label, Info $info) - { - if (1 === preg_match(Regex::RTL_LABEL, $label)) { - $info->bidiDomain = true; - - // Step 1. The first character must be a character with Bidi property L, R, or AL. - // If it has the R or AL property, it is an RTL label - if (1 !== preg_match(Regex::BIDI_STEP_1_RTL, $label)) { - $info->validBidiDomain = false; - - return; - } - - // Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES, - // CS, ET, ON, BN, or NSM are allowed. - if (1 === preg_match(Regex::BIDI_STEP_2, $label)) { - $info->validBidiDomain = false; - - return; - } - - // Step 3. In an RTL label, the end of the label must be a character with Bidi property - // R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM. - if (1 !== preg_match(Regex::BIDI_STEP_3, $label)) { - $info->validBidiDomain = false; - - return; - } - - // Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa. - if (1 === preg_match(Regex::BIDI_STEP_4_AN, $label) && 1 === preg_match(Regex::BIDI_STEP_4_EN, $label)) { - $info->validBidiDomain = false; - - return; - } - - return; - } - - // We are a LTR label - // Step 1. The first character must be a character with Bidi property L, R, or AL. - // If it has the L property, it is an LTR label. - if (1 !== preg_match(Regex::BIDI_STEP_1_LTR, $label)) { - $info->validBidiDomain = false; - - return; - } - - // Step 5. In an LTR label, only characters with the Bidi properties L, EN, - // ES, CS, ET, ON, BN, or NSM are allowed. - if (1 === preg_match(Regex::BIDI_STEP_5, $label)) { - $info->validBidiDomain = false; - - return; - } - - // Step 6.In an LTR label, the end of the label must be a character with Bidi property L or - // EN, followed by zero or more characters with Bidi property NSM. - if (1 !== preg_match(Regex::BIDI_STEP_6, $label)) { - $info->validBidiDomain = false; - - return; - } - } - - /** - * @param array $labels - */ - private static function validateDomainAndLabelLength(array $labels, Info $info) - { - $maxDomainSize = self::MAX_DOMAIN_SIZE; - $length = \count($labels); - - // Number of "." delimiters. - $domainLength = $length - 1; - - // If the last label is empty and it is not the first label, then it is the root label. - // Increase the max size by 1, making it 254, to account for the root label's "." - // delimiter. This also means we don't need to check the last label's length for being too - // long. - if ($length > 1 && '' === $labels[$length - 1]) { - ++$maxDomainSize; - --$length; - } - - for ($i = 0; $i < $length; ++$i) { - $bytes = \strlen($labels[$i]); - $domainLength += $bytes; - - if ($bytes > self::MAX_LABEL_SIZE) { - $info->errors |= self::ERROR_LABEL_TOO_LONG; - } - } - - if ($domainLength > $maxDomainSize) { - $info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG; - } - } - - /** - * @see https://www.unicode.org/reports/tr46/#Validity_Criteria - * - * @param string $label - * @param array $options - * @param bool $canBeEmpty - */ - private static function validateLabel($label, Info $info, array $options, $canBeEmpty) - { - if ('' === $label) { - if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) { - $info->errors |= self::ERROR_EMPTY_LABEL; - } - - return; - } - - // Step 1. The label must be in Unicode Normalization Form C. - if (!\Normalizer::isNormalized($label, \Normalizer::FORM_C)) { - $info->errors |= self::ERROR_INVALID_ACE_LABEL; - } - - $codePoints = self::utf8Decode($label); - - if ($options['CheckHyphens']) { - // Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character - // in both the thrid and fourth positions. - if (isset($codePoints[2], $codePoints[3]) && 0x002D === $codePoints[2] && 0x002D === $codePoints[3]) { - $info->errors |= self::ERROR_HYPHEN_3_4; - } - - // Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D - // HYPHEN-MINUS character. - if ('-' === substr($label, 0, 1)) { - $info->errors |= self::ERROR_LEADING_HYPHEN; - } - - if ('-' === substr($label, -1, 1)) { - $info->errors |= self::ERROR_TRAILING_HYPHEN; - } - } - - // Step 4. The label must not contain a U+002E (.) FULL STOP. - if (false !== strpos($label, '.')) { - $info->errors |= self::ERROR_LABEL_HAS_DOT; - } - - // Step 5. The label must not begin with a combining mark, that is: General_Category=Mark. - if (1 === preg_match(Regex::COMBINING_MARK, $label)) { - $info->errors |= self::ERROR_LEADING_COMBINING_MARK; - } - - // Step 6. Each code point in the label must only have certain status values according to - // Section 5, IDNA Mapping Table: - $transitional = $options['Transitional_Processing']; - $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; - - foreach ($codePoints as $codePoint) { - $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); - $status = $data['status']; - - if ('valid' === $status || (!$transitional && 'deviation' === $status)) { - continue; - } - - $info->errors |= self::ERROR_DISALLOWED; - - break; - } - - // Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in - // The Unicode Code Points and Internationalized Domain Names for Applications (IDNA) - // [IDNA2008]. - if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) { - $info->errors |= self::ERROR_CONTEXTJ; - } - - // Step 8. If CheckBidi, and if the domain name is a Bidi domain name, then the label must - // satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2. - if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) { - self::validateBidiLabel($label, $info); - } - } - - /** - * @see https://tools.ietf.org/html/rfc3492#section-6.2 - * - * @param string $input - * - * @return string - */ - private static function punycodeDecode($input) - { - $n = self::INITIAL_N; - $out = 0; - $i = 0; - $bias = self::INITIAL_BIAS; - $lastDelimIndex = strrpos($input, self::DELIMITER); - $b = false === $lastDelimIndex ? 0 : $lastDelimIndex; - $inputLength = \strlen($input); - $output = []; - $bytes = array_map('ord', str_split($input)); - - for ($j = 0; $j < $b; ++$j) { - if ($bytes[$j] > 0x7F) { - throw new \Exception('Invalid input'); - } - - $output[$out++] = $input[$j]; - } - - if ($b > 0) { - ++$b; - } - - for ($in = $b; $in < $inputLength; ++$out) { - $oldi = $i; - $w = 1; - - for ($k = self::BASE; /* no condition */; $k += self::BASE) { - if ($in >= $inputLength) { - throw new \Exception('Invalid input'); - } - - $digit = self::$basicToDigit[$bytes[$in++] & 0xFF]; - - if ($digit < 0) { - throw new \Exception('Invalid input'); - } - - if ($digit > intdiv(self::MAX_INT - $i, $w)) { - throw new \Exception('Integer overflow'); - } - - $i += $digit * $w; - - if ($k <= $bias) { - $t = self::TMIN; - } elseif ($k >= $bias + self::TMAX) { - $t = self::TMAX; - } else { - $t = $k - $bias; - } - - if ($digit < $t) { - break; - } - - $baseMinusT = self::BASE - $t; - - if ($w > intdiv(self::MAX_INT, $baseMinusT)) { - throw new \Exception('Integer overflow'); - } - - $w *= $baseMinusT; - } - - $outPlusOne = $out + 1; - $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi); - - if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) { - throw new \Exception('Integer overflow'); - } - - $n += intdiv($i, $outPlusOne); - $i %= $outPlusOne; - array_splice($output, $i++, 0, [mb_chr($n, 'utf-8')]); - } - - return implode('', $output); - } - - /** - * @see https://tools.ietf.org/html/rfc3492#section-6.3 - * - * @param string $input - * - * @return string - */ - private static function punycodeEncode($input) - { - $n = self::INITIAL_N; - $delta = 0; - $out = 0; - $bias = self::INITIAL_BIAS; - $inputLength = 0; - $output = ''; - $iter = self::utf8Decode($input); - - foreach ($iter as $codePoint) { - ++$inputLength; - - if ($codePoint < 0x80) { - $output .= \chr($codePoint); - ++$out; - } - } - - $h = $out; - $b = $out; - - if ($b > 0) { - $output .= self::DELIMITER; - ++$out; - } - - while ($h < $inputLength) { - $m = self::MAX_INT; - - foreach ($iter as $codePoint) { - if ($codePoint >= $n && $codePoint < $m) { - $m = $codePoint; - } - } - - if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) { - throw new \Exception('Integer overflow'); - } - - $delta += ($m - $n) * ($h + 1); - $n = $m; - - foreach ($iter as $codePoint) { - if ($codePoint < $n && 0 === ++$delta) { - throw new \Exception('Integer overflow'); - } - - if ($codePoint === $n) { - $q = $delta; - - for ($k = self::BASE; /* no condition */; $k += self::BASE) { - if ($k <= $bias) { - $t = self::TMIN; - } elseif ($k >= $bias + self::TMAX) { - $t = self::TMAX; - } else { - $t = $k - $bias; - } - - if ($q < $t) { - break; - } - - $qMinusT = $q - $t; - $baseMinusT = self::BASE - $t; - $output .= self::encodeDigit($t + $qMinusT % $baseMinusT, false); - ++$out; - $q = intdiv($qMinusT, $baseMinusT); - } - - $output .= self::encodeDigit($q, false); - ++$out; - $bias = self::adaptBias($delta, $h + 1, $h === $b); - $delta = 0; - ++$h; - } - } - - ++$delta; - ++$n; - } - - return $output; - } - - /** - * @see https://tools.ietf.org/html/rfc3492#section-6.1 - * - * @param int $delta - * @param int $numPoints - * @param bool $firstTime - * - * @return int - */ - private static function adaptBias($delta, $numPoints, $firstTime) - { - // xxx >> 1 is a faster way of doing intdiv(xxx, 2) - $delta = $firstTime ? intdiv($delta, self::DAMP) : $delta >> 1; - $delta += intdiv($delta, $numPoints); - $k = 0; - - while ($delta > ((self::BASE - self::TMIN) * self::TMAX) >> 1) { - $delta = intdiv($delta, self::BASE - self::TMIN); - $k += self::BASE; - } - - return $k + intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW); - } - - /** - * @param int $d - * @param bool $flag - * - * @return string - */ - private static function encodeDigit($d, $flag) - { - return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5)); - } - - /** - * Takes a UTF-8 encoded string and converts it into a series of integer code points. Any - * invalid byte sequences will be replaced by a U+FFFD replacement code point. - * - * @see https://encoding.spec.whatwg.org/#utf-8-decoder - * - * @param string $input - * - * @return array - */ - private static function utf8Decode($input) - { - $bytesSeen = 0; - $bytesNeeded = 0; - $lowerBoundary = 0x80; - $upperBoundary = 0xBF; - $codePoint = 0; - $codePoints = []; - $length = \strlen($input); - - for ($i = 0; $i < $length; ++$i) { - $byte = \ord($input[$i]); - - if (0 === $bytesNeeded) { - if ($byte >= 0x00 && $byte <= 0x7F) { - $codePoints[] = $byte; - - continue; - } - - if ($byte >= 0xC2 && $byte <= 0xDF) { - $bytesNeeded = 1; - $codePoint = $byte & 0x1F; - } elseif ($byte >= 0xE0 && $byte <= 0xEF) { - if (0xE0 === $byte) { - $lowerBoundary = 0xA0; - } elseif (0xED === $byte) { - $upperBoundary = 0x9F; - } - - $bytesNeeded = 2; - $codePoint = $byte & 0xF; - } elseif ($byte >= 0xF0 && $byte <= 0xF4) { - if (0xF0 === $byte) { - $lowerBoundary = 0x90; - } elseif (0xF4 === $byte) { - $upperBoundary = 0x8F; - } - - $bytesNeeded = 3; - $codePoint = $byte & 0x7; - } else { - $codePoints[] = 0xFFFD; - } - - continue; - } - - if ($byte < $lowerBoundary || $byte > $upperBoundary) { - $codePoint = 0; - $bytesNeeded = 0; - $bytesSeen = 0; - $lowerBoundary = 0x80; - $upperBoundary = 0xBF; - --$i; - $codePoints[] = 0xFFFD; - - continue; - } - - $lowerBoundary = 0x80; - $upperBoundary = 0xBF; - $codePoint = ($codePoint << 6) | ($byte & 0x3F); - - if (++$bytesSeen !== $bytesNeeded) { - continue; - } - - $codePoints[] = $codePoint; - $codePoint = 0; - $bytesNeeded = 0; - $bytesSeen = 0; - } - - // String unexpectedly ended, so append a U+FFFD code point. - if (0 !== $bytesNeeded) { - $codePoints[] = 0xFFFD; - } - - return $codePoints; - } - - /** - * @param int $codePoint - * @param bool $useSTD3ASCIIRules - * - * @return array{status: string, mapping?: string} - */ - private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules) - { - if (!self::$mappingTableLoaded) { - self::$mappingTableLoaded = true; - self::$mapped = require __DIR__.'/Resources/unidata/mapped.php'; - self::$ignored = require __DIR__.'/Resources/unidata/ignored.php'; - self::$deviation = require __DIR__.'/Resources/unidata/deviation.php'; - self::$disallowed = require __DIR__.'/Resources/unidata/disallowed.php'; - self::$disallowed_STD3_mapped = require __DIR__.'/Resources/unidata/disallowed_STD3_mapped.php'; - self::$disallowed_STD3_valid = require __DIR__.'/Resources/unidata/disallowed_STD3_valid.php'; - } - - if (isset(self::$mapped[$codePoint])) { - return ['status' => 'mapped', 'mapping' => self::$mapped[$codePoint]]; - } - - if (isset(self::$ignored[$codePoint])) { - return ['status' => 'ignored']; - } - - if (isset(self::$deviation[$codePoint])) { - return ['status' => 'deviation', 'mapping' => self::$deviation[$codePoint]]; - } - - if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) { - return ['status' => 'disallowed']; - } - - $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]); - - if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) { - $status = 'disallowed'; - - if (!$useSTD3ASCIIRules) { - $status = $isDisallowedMapped ? 'mapped' : 'valid'; - } - - if ($isDisallowedMapped) { - return ['status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]]; - } - - return ['status' => $status]; - } - - return ['status' => 'valid']; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Info.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Info.php deleted file mode 100644 index 25c3582b2..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Info.php +++ /dev/null @@ -1,23 +0,0 @@ - and Trevor Rowbotham - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Idn; - -/** - * @internal - */ -class Info -{ - public $bidiDomain = false; - public $errors = 0; - public $validBidiDomain = true; - public $transitionalDifferent = false; -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/LICENSE b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/LICENSE deleted file mode 100644 index fd0a0626a..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2018-present Fabien Potencier and Trevor Rowbotham - -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/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/README.md b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/README.md deleted file mode 100644 index cae551705..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / Intl: Idn -============================ - -This component provides [`idn_to_ascii`](https://php.net/idn-to-ascii) and [`idn_to_utf8`](https://php.net/idn-to-utf8) functions to users who run php versions without the [Intl](https://php.net/intl) extension. - -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/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php deleted file mode 100644 index d285acd13..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php +++ /dev/null @@ -1,384 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; - -/** - * @internal - */ -final class DisallowedRanges -{ - /** - * @param int $codePoint - * - * @return bool - */ - public static function inRange($codePoint) - { - if ($codePoint >= 128 && $codePoint <= 159) { - return true; - } - - if ($codePoint >= 2155 && $codePoint <= 2207) { - return true; - } - - if ($codePoint >= 3676 && $codePoint <= 3712) { - return true; - } - - if ($codePoint >= 3808 && $codePoint <= 3839) { - return true; - } - - if ($codePoint >= 4059 && $codePoint <= 4095) { - return true; - } - - if ($codePoint >= 4256 && $codePoint <= 4293) { - return true; - } - - if ($codePoint >= 6849 && $codePoint <= 6911) { - return true; - } - - if ($codePoint >= 11859 && $codePoint <= 11903) { - return true; - } - - if ($codePoint >= 42955 && $codePoint <= 42996) { - return true; - } - - if ($codePoint >= 55296 && $codePoint <= 57343) { - return true; - } - - if ($codePoint >= 57344 && $codePoint <= 63743) { - return true; - } - - if ($codePoint >= 64218 && $codePoint <= 64255) { - return true; - } - - if ($codePoint >= 64976 && $codePoint <= 65007) { - return true; - } - - if ($codePoint >= 65630 && $codePoint <= 65663) { - return true; - } - - if ($codePoint >= 65953 && $codePoint <= 65999) { - return true; - } - - if ($codePoint >= 66046 && $codePoint <= 66175) { - return true; - } - - if ($codePoint >= 66518 && $codePoint <= 66559) { - return true; - } - - if ($codePoint >= 66928 && $codePoint <= 67071) { - return true; - } - - if ($codePoint >= 67432 && $codePoint <= 67583) { - return true; - } - - if ($codePoint >= 67760 && $codePoint <= 67807) { - return true; - } - - if ($codePoint >= 67904 && $codePoint <= 67967) { - return true; - } - - if ($codePoint >= 68256 && $codePoint <= 68287) { - return true; - } - - if ($codePoint >= 68528 && $codePoint <= 68607) { - return true; - } - - if ($codePoint >= 68681 && $codePoint <= 68735) { - return true; - } - - if ($codePoint >= 68922 && $codePoint <= 69215) { - return true; - } - - if ($codePoint >= 69298 && $codePoint <= 69375) { - return true; - } - - if ($codePoint >= 69466 && $codePoint <= 69551) { - return true; - } - - if ($codePoint >= 70207 && $codePoint <= 70271) { - return true; - } - - if ($codePoint >= 70517 && $codePoint <= 70655) { - return true; - } - - if ($codePoint >= 70874 && $codePoint <= 71039) { - return true; - } - - if ($codePoint >= 71134 && $codePoint <= 71167) { - return true; - } - - if ($codePoint >= 71370 && $codePoint <= 71423) { - return true; - } - - if ($codePoint >= 71488 && $codePoint <= 71679) { - return true; - } - - if ($codePoint >= 71740 && $codePoint <= 71839) { - return true; - } - - if ($codePoint >= 72026 && $codePoint <= 72095) { - return true; - } - - if ($codePoint >= 72441 && $codePoint <= 72703) { - return true; - } - - if ($codePoint >= 72887 && $codePoint <= 72959) { - return true; - } - - if ($codePoint >= 73130 && $codePoint <= 73439) { - return true; - } - - if ($codePoint >= 73465 && $codePoint <= 73647) { - return true; - } - - if ($codePoint >= 74650 && $codePoint <= 74751) { - return true; - } - - if ($codePoint >= 75076 && $codePoint <= 77823) { - return true; - } - - if ($codePoint >= 78905 && $codePoint <= 82943) { - return true; - } - - if ($codePoint >= 83527 && $codePoint <= 92159) { - return true; - } - - if ($codePoint >= 92784 && $codePoint <= 92879) { - return true; - } - - if ($codePoint >= 93072 && $codePoint <= 93759) { - return true; - } - - if ($codePoint >= 93851 && $codePoint <= 93951) { - return true; - } - - if ($codePoint >= 94112 && $codePoint <= 94175) { - return true; - } - - if ($codePoint >= 101590 && $codePoint <= 101631) { - return true; - } - - if ($codePoint >= 101641 && $codePoint <= 110591) { - return true; - } - - if ($codePoint >= 110879 && $codePoint <= 110927) { - return true; - } - - if ($codePoint >= 111356 && $codePoint <= 113663) { - return true; - } - - if ($codePoint >= 113828 && $codePoint <= 118783) { - return true; - } - - if ($codePoint >= 119366 && $codePoint <= 119519) { - return true; - } - - if ($codePoint >= 119673 && $codePoint <= 119807) { - return true; - } - - if ($codePoint >= 121520 && $codePoint <= 122879) { - return true; - } - - if ($codePoint >= 122923 && $codePoint <= 123135) { - return true; - } - - if ($codePoint >= 123216 && $codePoint <= 123583) { - return true; - } - - if ($codePoint >= 123648 && $codePoint <= 124927) { - return true; - } - - if ($codePoint >= 125143 && $codePoint <= 125183) { - return true; - } - - if ($codePoint >= 125280 && $codePoint <= 126064) { - return true; - } - - if ($codePoint >= 126133 && $codePoint <= 126208) { - return true; - } - - if ($codePoint >= 126270 && $codePoint <= 126463) { - return true; - } - - if ($codePoint >= 126652 && $codePoint <= 126703) { - return true; - } - - if ($codePoint >= 126706 && $codePoint <= 126975) { - return true; - } - - if ($codePoint >= 127406 && $codePoint <= 127461) { - return true; - } - - if ($codePoint >= 127590 && $codePoint <= 127743) { - return true; - } - - if ($codePoint >= 129202 && $codePoint <= 129279) { - return true; - } - - if ($codePoint >= 129751 && $codePoint <= 129791) { - return true; - } - - if ($codePoint >= 129995 && $codePoint <= 130031) { - return true; - } - - if ($codePoint >= 130042 && $codePoint <= 131069) { - return true; - } - - if ($codePoint >= 173790 && $codePoint <= 173823) { - return true; - } - - if ($codePoint >= 191457 && $codePoint <= 194559) { - return true; - } - - if ($codePoint >= 195102 && $codePoint <= 196605) { - return true; - } - - if ($codePoint >= 201547 && $codePoint <= 262141) { - return true; - } - - if ($codePoint >= 262144 && $codePoint <= 327677) { - return true; - } - - if ($codePoint >= 327680 && $codePoint <= 393213) { - return true; - } - - if ($codePoint >= 393216 && $codePoint <= 458749) { - return true; - } - - if ($codePoint >= 458752 && $codePoint <= 524285) { - return true; - } - - if ($codePoint >= 524288 && $codePoint <= 589821) { - return true; - } - - if ($codePoint >= 589824 && $codePoint <= 655357) { - return true; - } - - if ($codePoint >= 655360 && $codePoint <= 720893) { - return true; - } - - if ($codePoint >= 720896 && $codePoint <= 786429) { - return true; - } - - if ($codePoint >= 786432 && $codePoint <= 851965) { - return true; - } - - if ($codePoint >= 851968 && $codePoint <= 917501) { - return true; - } - - if ($codePoint >= 917536 && $codePoint <= 917631) { - return true; - } - - if ($codePoint >= 917632 && $codePoint <= 917759) { - return true; - } - - if ($codePoint >= 918000 && $codePoint <= 983037) { - return true; - } - - if ($codePoint >= 983040 && $codePoint <= 1048573) { - return true; - } - - if ($codePoint >= 1048576 && $codePoint <= 1114109) { - return true; - } - - return false; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/Regex.php deleted file mode 100644 index 3c6af0c13..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/Regex.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; - -/** - * @internal - */ -final class Regex -{ - const COMBINING_MARK = '/^[\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{0903}\x{093A}\x{093B}\x{093C}\x{093E}-\x{0940}\x{0941}-\x{0948}\x{0949}-\x{094C}\x{094D}\x{094E}-\x{094F}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{0982}-\x{0983}\x{09BC}\x{09BE}-\x{09C0}\x{09C1}-\x{09C4}\x{09C7}-\x{09C8}\x{09CB}-\x{09CC}\x{09CD}\x{09D7}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A03}\x{0A3C}\x{0A3E}-\x{0A40}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0A83}\x{0ABC}\x{0ABE}-\x{0AC0}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0AC9}\x{0ACB}-\x{0ACC}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B02}-\x{0B03}\x{0B3C}\x{0B3E}\x{0B3F}\x{0B40}\x{0B41}-\x{0B44}\x{0B47}-\x{0B48}\x{0B4B}-\x{0B4C}\x{0B4D}\x{0B55}-\x{0B56}\x{0B57}\x{0B62}-\x{0B63}\x{0B82}\x{0BBE}-\x{0BBF}\x{0BC0}\x{0BC1}-\x{0BC2}\x{0BC6}-\x{0BC8}\x{0BCA}-\x{0BCC}\x{0BCD}\x{0BD7}\x{0C00}\x{0C01}-\x{0C03}\x{0C04}\x{0C3E}-\x{0C40}\x{0C41}-\x{0C44}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0C82}-\x{0C83}\x{0CBC}\x{0CBE}\x{0CBF}\x{0CC0}-\x{0CC4}\x{0CC6}\x{0CC7}-\x{0CC8}\x{0CCA}-\x{0CCB}\x{0CCC}-\x{0CCD}\x{0CD5}-\x{0CD6}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D02}-\x{0D03}\x{0D3B}-\x{0D3C}\x{0D3E}-\x{0D40}\x{0D41}-\x{0D44}\x{0D46}-\x{0D48}\x{0D4A}-\x{0D4C}\x{0D4D}\x{0D57}\x{0D62}-\x{0D63}\x{0D81}\x{0D82}-\x{0D83}\x{0DCA}\x{0DCF}-\x{0DD1}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0DD8}-\x{0DDF}\x{0DF2}-\x{0DF3}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3E}-\x{0F3F}\x{0F71}-\x{0F7E}\x{0F7F}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102B}-\x{102C}\x{102D}-\x{1030}\x{1031}\x{1032}-\x{1037}\x{1038}\x{1039}-\x{103A}\x{103B}-\x{103C}\x{103D}-\x{103E}\x{1056}-\x{1057}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106D}\x{1071}-\x{1074}\x{1082}\x{1083}-\x{1084}\x{1085}-\x{1086}\x{1087}-\x{108C}\x{108D}\x{108F}\x{109A}-\x{109C}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B6}\x{17B7}-\x{17BD}\x{17BE}-\x{17C5}\x{17C6}\x{17C7}-\x{17C8}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1923}-\x{1926}\x{1927}-\x{1928}\x{1929}-\x{192B}\x{1930}-\x{1931}\x{1932}\x{1933}-\x{1938}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A19}-\x{1A1A}\x{1A1B}\x{1A55}\x{1A56}\x{1A57}\x{1A58}-\x{1A5E}\x{1A60}\x{1A61}\x{1A62}\x{1A63}-\x{1A64}\x{1A65}-\x{1A6C}\x{1A6D}-\x{1A72}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B04}\x{1B34}\x{1B35}\x{1B36}-\x{1B3A}\x{1B3B}\x{1B3C}\x{1B3D}-\x{1B41}\x{1B42}\x{1B43}-\x{1B44}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1B82}\x{1BA1}\x{1BA2}-\x{1BA5}\x{1BA6}-\x{1BA7}\x{1BA8}-\x{1BA9}\x{1BAA}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE7}\x{1BE8}-\x{1BE9}\x{1BEA}-\x{1BEC}\x{1BED}\x{1BEE}\x{1BEF}-\x{1BF1}\x{1BF2}-\x{1BF3}\x{1C24}-\x{1C2B}\x{1C2C}-\x{1C33}\x{1C34}-\x{1C35}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE1}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF7}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{302E}-\x{302F}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A823}-\x{A824}\x{A825}-\x{A826}\x{A827}\x{A82C}\x{A880}-\x{A881}\x{A8B4}-\x{A8C3}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A952}-\x{A953}\x{A980}-\x{A982}\x{A983}\x{A9B3}\x{A9B4}-\x{A9B5}\x{A9B6}-\x{A9B9}\x{A9BA}-\x{A9BB}\x{A9BC}-\x{A9BD}\x{A9BE}-\x{A9C0}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA2F}-\x{AA30}\x{AA31}-\x{AA32}\x{AA33}-\x{AA34}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA4D}\x{AA7B}\x{AA7C}\x{AA7D}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEB}\x{AAEC}-\x{AAED}\x{AAEE}-\x{AAEF}\x{AAF5}\x{AAF6}\x{ABE3}-\x{ABE4}\x{ABE5}\x{ABE6}-\x{ABE7}\x{ABE8}\x{ABE9}-\x{ABEA}\x{ABEC}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11000}\x{11001}\x{11002}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{11082}\x{110B0}-\x{110B2}\x{110B3}-\x{110B6}\x{110B7}-\x{110B8}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112C}\x{1112D}-\x{11134}\x{11145}-\x{11146}\x{11173}\x{11180}-\x{11181}\x{11182}\x{111B3}-\x{111B5}\x{111B6}-\x{111BE}\x{111BF}-\x{111C0}\x{111C9}-\x{111CC}\x{111CE}\x{111CF}\x{1122C}-\x{1122E}\x{1122F}-\x{11231}\x{11232}-\x{11233}\x{11234}\x{11235}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E0}-\x{112E2}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{11302}-\x{11303}\x{1133B}-\x{1133C}\x{1133E}-\x{1133F}\x{11340}\x{11341}-\x{11344}\x{11347}-\x{11348}\x{1134B}-\x{1134D}\x{11357}\x{11362}-\x{11363}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11435}-\x{11437}\x{11438}-\x{1143F}\x{11440}-\x{11441}\x{11442}-\x{11444}\x{11445}\x{11446}\x{1145E}\x{114B0}-\x{114B2}\x{114B3}-\x{114B8}\x{114B9}\x{114BA}\x{114BB}-\x{114BE}\x{114BF}-\x{114C0}\x{114C1}\x{114C2}-\x{114C3}\x{115AF}-\x{115B1}\x{115B2}-\x{115B5}\x{115B8}-\x{115BB}\x{115BC}-\x{115BD}\x{115BE}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11630}-\x{11632}\x{11633}-\x{1163A}\x{1163B}-\x{1163C}\x{1163D}\x{1163E}\x{1163F}-\x{11640}\x{116AB}\x{116AC}\x{116AD}\x{116AE}-\x{116AF}\x{116B0}-\x{116B5}\x{116B6}\x{116B7}\x{1171D}-\x{1171F}\x{11720}-\x{11721}\x{11722}-\x{11725}\x{11726}\x{11727}-\x{1172B}\x{1182C}-\x{1182E}\x{1182F}-\x{11837}\x{11838}\x{11839}-\x{1183A}\x{11930}-\x{11935}\x{11937}-\x{11938}\x{1193B}-\x{1193C}\x{1193D}\x{1193E}\x{11940}\x{11942}\x{11943}\x{119D1}-\x{119D3}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119DC}-\x{119DF}\x{119E0}\x{119E4}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A39}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A57}-\x{11A58}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A97}\x{11A98}-\x{11A99}\x{11C2F}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3E}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CA9}\x{11CAA}-\x{11CB0}\x{11CB1}\x{11CB2}-\x{11CB3}\x{11CB4}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D8A}-\x{11D8E}\x{11D90}-\x{11D91}\x{11D93}-\x{11D94}\x{11D95}\x{11D96}\x{11D97}\x{11EF3}-\x{11EF4}\x{11EF5}-\x{11EF6}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F51}-\x{16F87}\x{16F8F}-\x{16F92}\x{16FE4}\x{16FF0}-\x{16FF1}\x{1BC9D}-\x{1BC9E}\x{1D165}-\x{1D166}\x{1D167}-\x{1D169}\x{1D16D}-\x{1D172}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]/u'; - - const RTL_LABEL = '/[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - - const BIDI_STEP_1_LTR = '/^[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; - const BIDI_STEP_1_RTL = '/^[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - const BIDI_STEP_2 = '/[^\x{0000}-\x{0008}\x{000E}-\x{001B}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{2060}-\x{2064}\x{2065}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; - const BIDI_STEP_3 = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1D7CE}-\x{1D7FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; - const BIDI_STEP_4_AN = '/[\x{0600}-\x{0605}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{06DD}\x{08E2}\x{10D30}-\x{10D39}\x{10E60}-\x{10E7E}]/u'; - const BIDI_STEP_4_EN = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{06F0}-\x{06F9}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{1D7CE}-\x{1D7FF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}]/u'; - const BIDI_STEP_5 = '/[\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0085}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{1680}\x{2000}-\x{200A}\x{200F}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{205F}\x{2066}\x{2067}\x{2068}\x{2069}\x{3000}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - const BIDI_STEP_6 = '/[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; - - const ZWNJ = '/([\x{A872}\x{10ACD}\x{10AD7}\x{10D00}\x{10FCB}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}][\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*\x{200C}[\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*)[\x{0622}-\x{0625}\x{0627}\x{0629}\x{062F}-\x{0632}\x{0648}\x{0671}-\x{0673}\x{0675}-\x{0677}\x{0688}-\x{0699}\x{06C0}\x{06C3}-\x{06CB}\x{06CD}\x{06CF}\x{06D2}-\x{06D3}\x{06D5}\x{06EE}-\x{06EF}\x{0710}\x{0715}-\x{0719}\x{071E}\x{0728}\x{072A}\x{072C}\x{072F}\x{074D}\x{0759}-\x{075B}\x{076B}-\x{076C}\x{0771}\x{0773}-\x{0774}\x{0778}-\x{0779}\x{0840}\x{0846}-\x{0847}\x{0849}\x{0854}\x{0856}-\x{0858}\x{0867}\x{0869}-\x{086A}\x{08AA}-\x{08AC}\x{08AE}\x{08B1}-\x{08B2}\x{08B9}\x{10AC5}\x{10AC7}\x{10AC9}-\x{10ACA}\x{10ACE}-\x{10AD2}\x{10ADD}\x{10AE1}\x{10AE4}\x{10AEF}\x{10B81}\x{10B83}-\x{10B85}\x{10B89}\x{10B8C}\x{10B8E}-\x{10B8F}\x{10B91}\x{10BA9}-\x{10BAC}\x{10D22}\x{10F33}\x{10F54}\x{10FB4}-\x{10FB6}\x{10FB9}-\x{10FBA}\x{10FBD}\x{10FC2}-\x{10FC3}\x{10FC9}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}]/u'; -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/deviation.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/deviation.php deleted file mode 100644 index 0bbd33567..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/deviation.php +++ /dev/null @@ -1,8 +0,0 @@ - 'ss', - 962 => 'σ', - 8204 => '', - 8205 => '', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php deleted file mode 100644 index 25a5f564d..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php +++ /dev/null @@ -1,2638 +0,0 @@ - true, - 889 => true, - 896 => true, - 897 => true, - 898 => true, - 899 => true, - 907 => true, - 909 => true, - 930 => true, - 1216 => true, - 1328 => true, - 1367 => true, - 1368 => true, - 1419 => true, - 1420 => true, - 1424 => true, - 1480 => true, - 1481 => true, - 1482 => true, - 1483 => true, - 1484 => true, - 1485 => true, - 1486 => true, - 1487 => true, - 1515 => true, - 1516 => true, - 1517 => true, - 1518 => true, - 1525 => true, - 1526 => true, - 1527 => true, - 1528 => true, - 1529 => true, - 1530 => true, - 1531 => true, - 1532 => true, - 1533 => true, - 1534 => true, - 1535 => true, - 1536 => true, - 1537 => true, - 1538 => true, - 1539 => true, - 1540 => true, - 1541 => true, - 1564 => true, - 1565 => true, - 1757 => true, - 1806 => true, - 1807 => true, - 1867 => true, - 1868 => true, - 1970 => true, - 1971 => true, - 1972 => true, - 1973 => true, - 1974 => true, - 1975 => true, - 1976 => true, - 1977 => true, - 1978 => true, - 1979 => true, - 1980 => true, - 1981 => true, - 1982 => true, - 1983 => true, - 2043 => true, - 2044 => true, - 2094 => true, - 2095 => true, - 2111 => true, - 2140 => true, - 2141 => true, - 2143 => true, - 2229 => true, - 2248 => true, - 2249 => true, - 2250 => true, - 2251 => true, - 2252 => true, - 2253 => true, - 2254 => true, - 2255 => true, - 2256 => true, - 2257 => true, - 2258 => true, - 2274 => true, - 2436 => true, - 2445 => true, - 2446 => true, - 2449 => true, - 2450 => true, - 2473 => true, - 2481 => true, - 2483 => true, - 2484 => true, - 2485 => true, - 2490 => true, - 2491 => true, - 2501 => true, - 2502 => true, - 2505 => true, - 2506 => true, - 2511 => true, - 2512 => true, - 2513 => true, - 2514 => true, - 2515 => true, - 2516 => true, - 2517 => true, - 2518 => true, - 2520 => true, - 2521 => true, - 2522 => true, - 2523 => true, - 2526 => true, - 2532 => true, - 2533 => true, - 2559 => true, - 2560 => true, - 2564 => true, - 2571 => true, - 2572 => true, - 2573 => true, - 2574 => true, - 2577 => true, - 2578 => true, - 2601 => true, - 2609 => true, - 2612 => true, - 2615 => true, - 2618 => true, - 2619 => true, - 2621 => true, - 2627 => true, - 2628 => true, - 2629 => true, - 2630 => true, - 2633 => true, - 2634 => true, - 2638 => true, - 2639 => true, - 2640 => true, - 2642 => true, - 2643 => true, - 2644 => true, - 2645 => true, - 2646 => true, - 2647 => true, - 2648 => true, - 2653 => true, - 2655 => true, - 2656 => true, - 2657 => true, - 2658 => true, - 2659 => true, - 2660 => true, - 2661 => true, - 2679 => true, - 2680 => true, - 2681 => true, - 2682 => true, - 2683 => true, - 2684 => true, - 2685 => true, - 2686 => true, - 2687 => true, - 2688 => true, - 2692 => true, - 2702 => true, - 2706 => true, - 2729 => true, - 2737 => true, - 2740 => true, - 2746 => true, - 2747 => true, - 2758 => true, - 2762 => true, - 2766 => true, - 2767 => true, - 2769 => true, - 2770 => true, - 2771 => true, - 2772 => true, - 2773 => true, - 2774 => true, - 2775 => true, - 2776 => true, - 2777 => true, - 2778 => true, - 2779 => true, - 2780 => true, - 2781 => true, - 2782 => true, - 2783 => true, - 2788 => true, - 2789 => true, - 2802 => true, - 2803 => true, - 2804 => true, - 2805 => true, - 2806 => true, - 2807 => true, - 2808 => true, - 2816 => true, - 2820 => true, - 2829 => true, - 2830 => true, - 2833 => true, - 2834 => true, - 2857 => true, - 2865 => true, - 2868 => true, - 2874 => true, - 2875 => true, - 2885 => true, - 2886 => true, - 2889 => true, - 2890 => true, - 2894 => true, - 2895 => true, - 2896 => true, - 2897 => true, - 2898 => true, - 2899 => true, - 2900 => true, - 2904 => true, - 2905 => true, - 2906 => true, - 2907 => true, - 2910 => true, - 2916 => true, - 2917 => true, - 2936 => true, - 2937 => true, - 2938 => true, - 2939 => true, - 2940 => true, - 2941 => true, - 2942 => true, - 2943 => true, - 2944 => true, - 2945 => true, - 2948 => true, - 2955 => true, - 2956 => true, - 2957 => true, - 2961 => true, - 2966 => true, - 2967 => true, - 2968 => true, - 2971 => true, - 2973 => true, - 2976 => true, - 2977 => true, - 2978 => true, - 2981 => true, - 2982 => true, - 2983 => true, - 2987 => true, - 2988 => true, - 2989 => true, - 3002 => true, - 3003 => true, - 3004 => true, - 3005 => true, - 3011 => true, - 3012 => true, - 3013 => true, - 3017 => true, - 3022 => true, - 3023 => true, - 3025 => true, - 3026 => true, - 3027 => true, - 3028 => true, - 3029 => true, - 3030 => true, - 3032 => true, - 3033 => true, - 3034 => true, - 3035 => true, - 3036 => true, - 3037 => true, - 3038 => true, - 3039 => true, - 3040 => true, - 3041 => true, - 3042 => true, - 3043 => true, - 3044 => true, - 3045 => true, - 3067 => true, - 3068 => true, - 3069 => true, - 3070 => true, - 3071 => true, - 3085 => true, - 3089 => true, - 3113 => true, - 3130 => true, - 3131 => true, - 3132 => true, - 3141 => true, - 3145 => true, - 3150 => true, - 3151 => true, - 3152 => true, - 3153 => true, - 3154 => true, - 3155 => true, - 3156 => true, - 3159 => true, - 3163 => true, - 3164 => true, - 3165 => true, - 3166 => true, - 3167 => true, - 3172 => true, - 3173 => true, - 3184 => true, - 3185 => true, - 3186 => true, - 3187 => true, - 3188 => true, - 3189 => true, - 3190 => true, - 3213 => true, - 3217 => true, - 3241 => true, - 3252 => true, - 3258 => true, - 3259 => true, - 3269 => true, - 3273 => true, - 3278 => true, - 3279 => true, - 3280 => true, - 3281 => true, - 3282 => true, - 3283 => true, - 3284 => true, - 3287 => true, - 3288 => true, - 3289 => true, - 3290 => true, - 3291 => true, - 3292 => true, - 3293 => true, - 3295 => true, - 3300 => true, - 3301 => true, - 3312 => true, - 3315 => true, - 3316 => true, - 3317 => true, - 3318 => true, - 3319 => true, - 3320 => true, - 3321 => true, - 3322 => true, - 3323 => true, - 3324 => true, - 3325 => true, - 3326 => true, - 3327 => true, - 3341 => true, - 3345 => true, - 3397 => true, - 3401 => true, - 3408 => true, - 3409 => true, - 3410 => true, - 3411 => true, - 3428 => true, - 3429 => true, - 3456 => true, - 3460 => true, - 3479 => true, - 3480 => true, - 3481 => true, - 3506 => true, - 3516 => true, - 3518 => true, - 3519 => true, - 3527 => true, - 3528 => true, - 3529 => true, - 3531 => true, - 3532 => true, - 3533 => true, - 3534 => true, - 3541 => true, - 3543 => true, - 3552 => true, - 3553 => true, - 3554 => true, - 3555 => true, - 3556 => true, - 3557 => true, - 3568 => true, - 3569 => true, - 3573 => true, - 3574 => true, - 3575 => true, - 3576 => true, - 3577 => true, - 3578 => true, - 3579 => true, - 3580 => true, - 3581 => true, - 3582 => true, - 3583 => true, - 3584 => true, - 3643 => true, - 3644 => true, - 3645 => true, - 3646 => true, - 3715 => true, - 3717 => true, - 3723 => true, - 3748 => true, - 3750 => true, - 3774 => true, - 3775 => true, - 3781 => true, - 3783 => true, - 3790 => true, - 3791 => true, - 3802 => true, - 3803 => true, - 3912 => true, - 3949 => true, - 3950 => true, - 3951 => true, - 3952 => true, - 3992 => true, - 4029 => true, - 4045 => true, - 4294 => true, - 4296 => true, - 4297 => true, - 4298 => true, - 4299 => true, - 4300 => true, - 4302 => true, - 4303 => true, - 4447 => true, - 4448 => true, - 4681 => true, - 4686 => true, - 4687 => true, - 4695 => true, - 4697 => true, - 4702 => true, - 4703 => true, - 4745 => true, - 4750 => true, - 4751 => true, - 4785 => true, - 4790 => true, - 4791 => true, - 4799 => true, - 4801 => true, - 4806 => true, - 4807 => true, - 4823 => true, - 4881 => true, - 4886 => true, - 4887 => true, - 4955 => true, - 4956 => true, - 4989 => true, - 4990 => true, - 4991 => true, - 5018 => true, - 5019 => true, - 5020 => true, - 5021 => true, - 5022 => true, - 5023 => true, - 5110 => true, - 5111 => true, - 5118 => true, - 5119 => true, - 5760 => true, - 5789 => true, - 5790 => true, - 5791 => true, - 5881 => true, - 5882 => true, - 5883 => true, - 5884 => true, - 5885 => true, - 5886 => true, - 5887 => true, - 5901 => true, - 5909 => true, - 5910 => true, - 5911 => true, - 5912 => true, - 5913 => true, - 5914 => true, - 5915 => true, - 5916 => true, - 5917 => true, - 5918 => true, - 5919 => true, - 5943 => true, - 5944 => true, - 5945 => true, - 5946 => true, - 5947 => true, - 5948 => true, - 5949 => true, - 5950 => true, - 5951 => true, - 5972 => true, - 5973 => true, - 5974 => true, - 5975 => true, - 5976 => true, - 5977 => true, - 5978 => true, - 5979 => true, - 5980 => true, - 5981 => true, - 5982 => true, - 5983 => true, - 5997 => true, - 6001 => true, - 6004 => true, - 6005 => true, - 6006 => true, - 6007 => true, - 6008 => true, - 6009 => true, - 6010 => true, - 6011 => true, - 6012 => true, - 6013 => true, - 6014 => true, - 6015 => true, - 6068 => true, - 6069 => true, - 6110 => true, - 6111 => true, - 6122 => true, - 6123 => true, - 6124 => true, - 6125 => true, - 6126 => true, - 6127 => true, - 6138 => true, - 6139 => true, - 6140 => true, - 6141 => true, - 6142 => true, - 6143 => true, - 6150 => true, - 6158 => true, - 6159 => true, - 6170 => true, - 6171 => true, - 6172 => true, - 6173 => true, - 6174 => true, - 6175 => true, - 6265 => true, - 6266 => true, - 6267 => true, - 6268 => true, - 6269 => true, - 6270 => true, - 6271 => true, - 6315 => true, - 6316 => true, - 6317 => true, - 6318 => true, - 6319 => true, - 6390 => true, - 6391 => true, - 6392 => true, - 6393 => true, - 6394 => true, - 6395 => true, - 6396 => true, - 6397 => true, - 6398 => true, - 6399 => true, - 6431 => true, - 6444 => true, - 6445 => true, - 6446 => true, - 6447 => true, - 6460 => true, - 6461 => true, - 6462 => true, - 6463 => true, - 6465 => true, - 6466 => true, - 6467 => true, - 6510 => true, - 6511 => true, - 6517 => true, - 6518 => true, - 6519 => true, - 6520 => true, - 6521 => true, - 6522 => true, - 6523 => true, - 6524 => true, - 6525 => true, - 6526 => true, - 6527 => true, - 6572 => true, - 6573 => true, - 6574 => true, - 6575 => true, - 6602 => true, - 6603 => true, - 6604 => true, - 6605 => true, - 6606 => true, - 6607 => true, - 6619 => true, - 6620 => true, - 6621 => true, - 6684 => true, - 6685 => true, - 6751 => true, - 6781 => true, - 6782 => true, - 6794 => true, - 6795 => true, - 6796 => true, - 6797 => true, - 6798 => true, - 6799 => true, - 6810 => true, - 6811 => true, - 6812 => true, - 6813 => true, - 6814 => true, - 6815 => true, - 6830 => true, - 6831 => true, - 6988 => true, - 6989 => true, - 6990 => true, - 6991 => true, - 7037 => true, - 7038 => true, - 7039 => true, - 7156 => true, - 7157 => true, - 7158 => true, - 7159 => true, - 7160 => true, - 7161 => true, - 7162 => true, - 7163 => true, - 7224 => true, - 7225 => true, - 7226 => true, - 7242 => true, - 7243 => true, - 7244 => true, - 7305 => true, - 7306 => true, - 7307 => true, - 7308 => true, - 7309 => true, - 7310 => true, - 7311 => true, - 7355 => true, - 7356 => true, - 7368 => true, - 7369 => true, - 7370 => true, - 7371 => true, - 7372 => true, - 7373 => true, - 7374 => true, - 7375 => true, - 7419 => true, - 7420 => true, - 7421 => true, - 7422 => true, - 7423 => true, - 7674 => true, - 7958 => true, - 7959 => true, - 7966 => true, - 7967 => true, - 8006 => true, - 8007 => true, - 8014 => true, - 8015 => true, - 8024 => true, - 8026 => true, - 8028 => true, - 8030 => true, - 8062 => true, - 8063 => true, - 8117 => true, - 8133 => true, - 8148 => true, - 8149 => true, - 8156 => true, - 8176 => true, - 8177 => true, - 8181 => true, - 8191 => true, - 8206 => true, - 8207 => true, - 8228 => true, - 8229 => true, - 8230 => true, - 8232 => true, - 8233 => true, - 8234 => true, - 8235 => true, - 8236 => true, - 8237 => true, - 8238 => true, - 8289 => true, - 8290 => true, - 8291 => true, - 8293 => true, - 8294 => true, - 8295 => true, - 8296 => true, - 8297 => true, - 8298 => true, - 8299 => true, - 8300 => true, - 8301 => true, - 8302 => true, - 8303 => true, - 8306 => true, - 8307 => true, - 8335 => true, - 8349 => true, - 8350 => true, - 8351 => true, - 8384 => true, - 8385 => true, - 8386 => true, - 8387 => true, - 8388 => true, - 8389 => true, - 8390 => true, - 8391 => true, - 8392 => true, - 8393 => true, - 8394 => true, - 8395 => true, - 8396 => true, - 8397 => true, - 8398 => true, - 8399 => true, - 8433 => true, - 8434 => true, - 8435 => true, - 8436 => true, - 8437 => true, - 8438 => true, - 8439 => true, - 8440 => true, - 8441 => true, - 8442 => true, - 8443 => true, - 8444 => true, - 8445 => true, - 8446 => true, - 8447 => true, - 8498 => true, - 8579 => true, - 8588 => true, - 8589 => true, - 8590 => true, - 8591 => true, - 9255 => true, - 9256 => true, - 9257 => true, - 9258 => true, - 9259 => true, - 9260 => true, - 9261 => true, - 9262 => true, - 9263 => true, - 9264 => true, - 9265 => true, - 9266 => true, - 9267 => true, - 9268 => true, - 9269 => true, - 9270 => true, - 9271 => true, - 9272 => true, - 9273 => true, - 9274 => true, - 9275 => true, - 9276 => true, - 9277 => true, - 9278 => true, - 9279 => true, - 9291 => true, - 9292 => true, - 9293 => true, - 9294 => true, - 9295 => true, - 9296 => true, - 9297 => true, - 9298 => true, - 9299 => true, - 9300 => true, - 9301 => true, - 9302 => true, - 9303 => true, - 9304 => true, - 9305 => true, - 9306 => true, - 9307 => true, - 9308 => true, - 9309 => true, - 9310 => true, - 9311 => true, - 9352 => true, - 9353 => true, - 9354 => true, - 9355 => true, - 9356 => true, - 9357 => true, - 9358 => true, - 9359 => true, - 9360 => true, - 9361 => true, - 9362 => true, - 9363 => true, - 9364 => true, - 9365 => true, - 9366 => true, - 9367 => true, - 9368 => true, - 9369 => true, - 9370 => true, - 9371 => true, - 11124 => true, - 11125 => true, - 11158 => true, - 11311 => true, - 11359 => true, - 11508 => true, - 11509 => true, - 11510 => true, - 11511 => true, - 11512 => true, - 11558 => true, - 11560 => true, - 11561 => true, - 11562 => true, - 11563 => true, - 11564 => true, - 11566 => true, - 11567 => true, - 11624 => true, - 11625 => true, - 11626 => true, - 11627 => true, - 11628 => true, - 11629 => true, - 11630 => true, - 11633 => true, - 11634 => true, - 11635 => true, - 11636 => true, - 11637 => true, - 11638 => true, - 11639 => true, - 11640 => true, - 11641 => true, - 11642 => true, - 11643 => true, - 11644 => true, - 11645 => true, - 11646 => true, - 11671 => true, - 11672 => true, - 11673 => true, - 11674 => true, - 11675 => true, - 11676 => true, - 11677 => true, - 11678 => true, - 11679 => true, - 11687 => true, - 11695 => true, - 11703 => true, - 11711 => true, - 11719 => true, - 11727 => true, - 11735 => true, - 11743 => true, - 11930 => true, - 12020 => true, - 12021 => true, - 12022 => true, - 12023 => true, - 12024 => true, - 12025 => true, - 12026 => true, - 12027 => true, - 12028 => true, - 12029 => true, - 12030 => true, - 12031 => true, - 12246 => true, - 12247 => true, - 12248 => true, - 12249 => true, - 12250 => true, - 12251 => true, - 12252 => true, - 12253 => true, - 12254 => true, - 12255 => true, - 12256 => true, - 12257 => true, - 12258 => true, - 12259 => true, - 12260 => true, - 12261 => true, - 12262 => true, - 12263 => true, - 12264 => true, - 12265 => true, - 12266 => true, - 12267 => true, - 12268 => true, - 12269 => true, - 12270 => true, - 12271 => true, - 12272 => true, - 12273 => true, - 12274 => true, - 12275 => true, - 12276 => true, - 12277 => true, - 12278 => true, - 12279 => true, - 12280 => true, - 12281 => true, - 12282 => true, - 12283 => true, - 12284 => true, - 12285 => true, - 12286 => true, - 12287 => true, - 12352 => true, - 12439 => true, - 12440 => true, - 12544 => true, - 12545 => true, - 12546 => true, - 12547 => true, - 12548 => true, - 12592 => true, - 12644 => true, - 12687 => true, - 12772 => true, - 12773 => true, - 12774 => true, - 12775 => true, - 12776 => true, - 12777 => true, - 12778 => true, - 12779 => true, - 12780 => true, - 12781 => true, - 12782 => true, - 12783 => true, - 12831 => true, - 13250 => true, - 13255 => true, - 13272 => true, - 40957 => true, - 40958 => true, - 40959 => true, - 42125 => true, - 42126 => true, - 42127 => true, - 42183 => true, - 42184 => true, - 42185 => true, - 42186 => true, - 42187 => true, - 42188 => true, - 42189 => true, - 42190 => true, - 42191 => true, - 42540 => true, - 42541 => true, - 42542 => true, - 42543 => true, - 42544 => true, - 42545 => true, - 42546 => true, - 42547 => true, - 42548 => true, - 42549 => true, - 42550 => true, - 42551 => true, - 42552 => true, - 42553 => true, - 42554 => true, - 42555 => true, - 42556 => true, - 42557 => true, - 42558 => true, - 42559 => true, - 42744 => true, - 42745 => true, - 42746 => true, - 42747 => true, - 42748 => true, - 42749 => true, - 42750 => true, - 42751 => true, - 42944 => true, - 42945 => true, - 43053 => true, - 43054 => true, - 43055 => true, - 43066 => true, - 43067 => true, - 43068 => true, - 43069 => true, - 43070 => true, - 43071 => true, - 43128 => true, - 43129 => true, - 43130 => true, - 43131 => true, - 43132 => true, - 43133 => true, - 43134 => true, - 43135 => true, - 43206 => true, - 43207 => true, - 43208 => true, - 43209 => true, - 43210 => true, - 43211 => true, - 43212 => true, - 43213 => true, - 43226 => true, - 43227 => true, - 43228 => true, - 43229 => true, - 43230 => true, - 43231 => true, - 43348 => true, - 43349 => true, - 43350 => true, - 43351 => true, - 43352 => true, - 43353 => true, - 43354 => true, - 43355 => true, - 43356 => true, - 43357 => true, - 43358 => true, - 43389 => true, - 43390 => true, - 43391 => true, - 43470 => true, - 43482 => true, - 43483 => true, - 43484 => true, - 43485 => true, - 43519 => true, - 43575 => true, - 43576 => true, - 43577 => true, - 43578 => true, - 43579 => true, - 43580 => true, - 43581 => true, - 43582 => true, - 43583 => true, - 43598 => true, - 43599 => true, - 43610 => true, - 43611 => true, - 43715 => true, - 43716 => true, - 43717 => true, - 43718 => true, - 43719 => true, - 43720 => true, - 43721 => true, - 43722 => true, - 43723 => true, - 43724 => true, - 43725 => true, - 43726 => true, - 43727 => true, - 43728 => true, - 43729 => true, - 43730 => true, - 43731 => true, - 43732 => true, - 43733 => true, - 43734 => true, - 43735 => true, - 43736 => true, - 43737 => true, - 43738 => true, - 43767 => true, - 43768 => true, - 43769 => true, - 43770 => true, - 43771 => true, - 43772 => true, - 43773 => true, - 43774 => true, - 43775 => true, - 43776 => true, - 43783 => true, - 43784 => true, - 43791 => true, - 43792 => true, - 43799 => true, - 43800 => true, - 43801 => true, - 43802 => true, - 43803 => true, - 43804 => true, - 43805 => true, - 43806 => true, - 43807 => true, - 43815 => true, - 43823 => true, - 43884 => true, - 43885 => true, - 43886 => true, - 43887 => true, - 44014 => true, - 44015 => true, - 44026 => true, - 44027 => true, - 44028 => true, - 44029 => true, - 44030 => true, - 44031 => true, - 55204 => true, - 55205 => true, - 55206 => true, - 55207 => true, - 55208 => true, - 55209 => true, - 55210 => true, - 55211 => true, - 55212 => true, - 55213 => true, - 55214 => true, - 55215 => true, - 55239 => true, - 55240 => true, - 55241 => true, - 55242 => true, - 55292 => true, - 55293 => true, - 55294 => true, - 55295 => true, - 64110 => true, - 64111 => true, - 64263 => true, - 64264 => true, - 64265 => true, - 64266 => true, - 64267 => true, - 64268 => true, - 64269 => true, - 64270 => true, - 64271 => true, - 64272 => true, - 64273 => true, - 64274 => true, - 64280 => true, - 64281 => true, - 64282 => true, - 64283 => true, - 64284 => true, - 64311 => true, - 64317 => true, - 64319 => true, - 64322 => true, - 64325 => true, - 64450 => true, - 64451 => true, - 64452 => true, - 64453 => true, - 64454 => true, - 64455 => true, - 64456 => true, - 64457 => true, - 64458 => true, - 64459 => true, - 64460 => true, - 64461 => true, - 64462 => true, - 64463 => true, - 64464 => true, - 64465 => true, - 64466 => true, - 64832 => true, - 64833 => true, - 64834 => true, - 64835 => true, - 64836 => true, - 64837 => true, - 64838 => true, - 64839 => true, - 64840 => true, - 64841 => true, - 64842 => true, - 64843 => true, - 64844 => true, - 64845 => true, - 64846 => true, - 64847 => true, - 64912 => true, - 64913 => true, - 64968 => true, - 64969 => true, - 64970 => true, - 64971 => true, - 64972 => true, - 64973 => true, - 64974 => true, - 64975 => true, - 65022 => true, - 65023 => true, - 65042 => true, - 65049 => true, - 65050 => true, - 65051 => true, - 65052 => true, - 65053 => true, - 65054 => true, - 65055 => true, - 65072 => true, - 65106 => true, - 65107 => true, - 65127 => true, - 65132 => true, - 65133 => true, - 65134 => true, - 65135 => true, - 65141 => true, - 65277 => true, - 65278 => true, - 65280 => true, - 65440 => true, - 65471 => true, - 65472 => true, - 65473 => true, - 65480 => true, - 65481 => true, - 65488 => true, - 65489 => true, - 65496 => true, - 65497 => true, - 65501 => true, - 65502 => true, - 65503 => true, - 65511 => true, - 65519 => true, - 65520 => true, - 65521 => true, - 65522 => true, - 65523 => true, - 65524 => true, - 65525 => true, - 65526 => true, - 65527 => true, - 65528 => true, - 65529 => true, - 65530 => true, - 65531 => true, - 65532 => true, - 65533 => true, - 65534 => true, - 65535 => true, - 65548 => true, - 65575 => true, - 65595 => true, - 65598 => true, - 65614 => true, - 65615 => true, - 65787 => true, - 65788 => true, - 65789 => true, - 65790 => true, - 65791 => true, - 65795 => true, - 65796 => true, - 65797 => true, - 65798 => true, - 65844 => true, - 65845 => true, - 65846 => true, - 65935 => true, - 65949 => true, - 65950 => true, - 65951 => true, - 66205 => true, - 66206 => true, - 66207 => true, - 66257 => true, - 66258 => true, - 66259 => true, - 66260 => true, - 66261 => true, - 66262 => true, - 66263 => true, - 66264 => true, - 66265 => true, - 66266 => true, - 66267 => true, - 66268 => true, - 66269 => true, - 66270 => true, - 66271 => true, - 66300 => true, - 66301 => true, - 66302 => true, - 66303 => true, - 66340 => true, - 66341 => true, - 66342 => true, - 66343 => true, - 66344 => true, - 66345 => true, - 66346 => true, - 66347 => true, - 66348 => true, - 66379 => true, - 66380 => true, - 66381 => true, - 66382 => true, - 66383 => true, - 66427 => true, - 66428 => true, - 66429 => true, - 66430 => true, - 66431 => true, - 66462 => true, - 66500 => true, - 66501 => true, - 66502 => true, - 66503 => true, - 66718 => true, - 66719 => true, - 66730 => true, - 66731 => true, - 66732 => true, - 66733 => true, - 66734 => true, - 66735 => true, - 66772 => true, - 66773 => true, - 66774 => true, - 66775 => true, - 66812 => true, - 66813 => true, - 66814 => true, - 66815 => true, - 66856 => true, - 66857 => true, - 66858 => true, - 66859 => true, - 66860 => true, - 66861 => true, - 66862 => true, - 66863 => true, - 66916 => true, - 66917 => true, - 66918 => true, - 66919 => true, - 66920 => true, - 66921 => true, - 66922 => true, - 66923 => true, - 66924 => true, - 66925 => true, - 66926 => true, - 67383 => true, - 67384 => true, - 67385 => true, - 67386 => true, - 67387 => true, - 67388 => true, - 67389 => true, - 67390 => true, - 67391 => true, - 67414 => true, - 67415 => true, - 67416 => true, - 67417 => true, - 67418 => true, - 67419 => true, - 67420 => true, - 67421 => true, - 67422 => true, - 67423 => true, - 67590 => true, - 67591 => true, - 67593 => true, - 67638 => true, - 67641 => true, - 67642 => true, - 67643 => true, - 67645 => true, - 67646 => true, - 67670 => true, - 67743 => true, - 67744 => true, - 67745 => true, - 67746 => true, - 67747 => true, - 67748 => true, - 67749 => true, - 67750 => true, - 67827 => true, - 67830 => true, - 67831 => true, - 67832 => true, - 67833 => true, - 67834 => true, - 67868 => true, - 67869 => true, - 67870 => true, - 67898 => true, - 67899 => true, - 67900 => true, - 67901 => true, - 67902 => true, - 68024 => true, - 68025 => true, - 68026 => true, - 68027 => true, - 68048 => true, - 68049 => true, - 68100 => true, - 68103 => true, - 68104 => true, - 68105 => true, - 68106 => true, - 68107 => true, - 68116 => true, - 68120 => true, - 68150 => true, - 68151 => true, - 68155 => true, - 68156 => true, - 68157 => true, - 68158 => true, - 68169 => true, - 68170 => true, - 68171 => true, - 68172 => true, - 68173 => true, - 68174 => true, - 68175 => true, - 68185 => true, - 68186 => true, - 68187 => true, - 68188 => true, - 68189 => true, - 68190 => true, - 68191 => true, - 68327 => true, - 68328 => true, - 68329 => true, - 68330 => true, - 68343 => true, - 68344 => true, - 68345 => true, - 68346 => true, - 68347 => true, - 68348 => true, - 68349 => true, - 68350 => true, - 68351 => true, - 68406 => true, - 68407 => true, - 68408 => true, - 68438 => true, - 68439 => true, - 68467 => true, - 68468 => true, - 68469 => true, - 68470 => true, - 68471 => true, - 68498 => true, - 68499 => true, - 68500 => true, - 68501 => true, - 68502 => true, - 68503 => true, - 68504 => true, - 68509 => true, - 68510 => true, - 68511 => true, - 68512 => true, - 68513 => true, - 68514 => true, - 68515 => true, - 68516 => true, - 68517 => true, - 68518 => true, - 68519 => true, - 68520 => true, - 68787 => true, - 68788 => true, - 68789 => true, - 68790 => true, - 68791 => true, - 68792 => true, - 68793 => true, - 68794 => true, - 68795 => true, - 68796 => true, - 68797 => true, - 68798 => true, - 68799 => true, - 68851 => true, - 68852 => true, - 68853 => true, - 68854 => true, - 68855 => true, - 68856 => true, - 68857 => true, - 68904 => true, - 68905 => true, - 68906 => true, - 68907 => true, - 68908 => true, - 68909 => true, - 68910 => true, - 68911 => true, - 69247 => true, - 69290 => true, - 69294 => true, - 69295 => true, - 69416 => true, - 69417 => true, - 69418 => true, - 69419 => true, - 69420 => true, - 69421 => true, - 69422 => true, - 69423 => true, - 69580 => true, - 69581 => true, - 69582 => true, - 69583 => true, - 69584 => true, - 69585 => true, - 69586 => true, - 69587 => true, - 69588 => true, - 69589 => true, - 69590 => true, - 69591 => true, - 69592 => true, - 69593 => true, - 69594 => true, - 69595 => true, - 69596 => true, - 69597 => true, - 69598 => true, - 69599 => true, - 69623 => true, - 69624 => true, - 69625 => true, - 69626 => true, - 69627 => true, - 69628 => true, - 69629 => true, - 69630 => true, - 69631 => true, - 69710 => true, - 69711 => true, - 69712 => true, - 69713 => true, - 69744 => true, - 69745 => true, - 69746 => true, - 69747 => true, - 69748 => true, - 69749 => true, - 69750 => true, - 69751 => true, - 69752 => true, - 69753 => true, - 69754 => true, - 69755 => true, - 69756 => true, - 69757 => true, - 69758 => true, - 69821 => true, - 69826 => true, - 69827 => true, - 69828 => true, - 69829 => true, - 69830 => true, - 69831 => true, - 69832 => true, - 69833 => true, - 69834 => true, - 69835 => true, - 69836 => true, - 69837 => true, - 69838 => true, - 69839 => true, - 69865 => true, - 69866 => true, - 69867 => true, - 69868 => true, - 69869 => true, - 69870 => true, - 69871 => true, - 69882 => true, - 69883 => true, - 69884 => true, - 69885 => true, - 69886 => true, - 69887 => true, - 69941 => true, - 69960 => true, - 69961 => true, - 69962 => true, - 69963 => true, - 69964 => true, - 69965 => true, - 69966 => true, - 69967 => true, - 70007 => true, - 70008 => true, - 70009 => true, - 70010 => true, - 70011 => true, - 70012 => true, - 70013 => true, - 70014 => true, - 70015 => true, - 70112 => true, - 70133 => true, - 70134 => true, - 70135 => true, - 70136 => true, - 70137 => true, - 70138 => true, - 70139 => true, - 70140 => true, - 70141 => true, - 70142 => true, - 70143 => true, - 70162 => true, - 70279 => true, - 70281 => true, - 70286 => true, - 70302 => true, - 70314 => true, - 70315 => true, - 70316 => true, - 70317 => true, - 70318 => true, - 70319 => true, - 70379 => true, - 70380 => true, - 70381 => true, - 70382 => true, - 70383 => true, - 70394 => true, - 70395 => true, - 70396 => true, - 70397 => true, - 70398 => true, - 70399 => true, - 70404 => true, - 70413 => true, - 70414 => true, - 70417 => true, - 70418 => true, - 70441 => true, - 70449 => true, - 70452 => true, - 70458 => true, - 70469 => true, - 70470 => true, - 70473 => true, - 70474 => true, - 70478 => true, - 70479 => true, - 70481 => true, - 70482 => true, - 70483 => true, - 70484 => true, - 70485 => true, - 70486 => true, - 70488 => true, - 70489 => true, - 70490 => true, - 70491 => true, - 70492 => true, - 70500 => true, - 70501 => true, - 70509 => true, - 70510 => true, - 70511 => true, - 70748 => true, - 70754 => true, - 70755 => true, - 70756 => true, - 70757 => true, - 70758 => true, - 70759 => true, - 70760 => true, - 70761 => true, - 70762 => true, - 70763 => true, - 70764 => true, - 70765 => true, - 70766 => true, - 70767 => true, - 70768 => true, - 70769 => true, - 70770 => true, - 70771 => true, - 70772 => true, - 70773 => true, - 70774 => true, - 70775 => true, - 70776 => true, - 70777 => true, - 70778 => true, - 70779 => true, - 70780 => true, - 70781 => true, - 70782 => true, - 70783 => true, - 70856 => true, - 70857 => true, - 70858 => true, - 70859 => true, - 70860 => true, - 70861 => true, - 70862 => true, - 70863 => true, - 71094 => true, - 71095 => true, - 71237 => true, - 71238 => true, - 71239 => true, - 71240 => true, - 71241 => true, - 71242 => true, - 71243 => true, - 71244 => true, - 71245 => true, - 71246 => true, - 71247 => true, - 71258 => true, - 71259 => true, - 71260 => true, - 71261 => true, - 71262 => true, - 71263 => true, - 71277 => true, - 71278 => true, - 71279 => true, - 71280 => true, - 71281 => true, - 71282 => true, - 71283 => true, - 71284 => true, - 71285 => true, - 71286 => true, - 71287 => true, - 71288 => true, - 71289 => true, - 71290 => true, - 71291 => true, - 71292 => true, - 71293 => true, - 71294 => true, - 71295 => true, - 71353 => true, - 71354 => true, - 71355 => true, - 71356 => true, - 71357 => true, - 71358 => true, - 71359 => true, - 71451 => true, - 71452 => true, - 71468 => true, - 71469 => true, - 71470 => true, - 71471 => true, - 71923 => true, - 71924 => true, - 71925 => true, - 71926 => true, - 71927 => true, - 71928 => true, - 71929 => true, - 71930 => true, - 71931 => true, - 71932 => true, - 71933 => true, - 71934 => true, - 71943 => true, - 71944 => true, - 71946 => true, - 71947 => true, - 71956 => true, - 71959 => true, - 71990 => true, - 71993 => true, - 71994 => true, - 72007 => true, - 72008 => true, - 72009 => true, - 72010 => true, - 72011 => true, - 72012 => true, - 72013 => true, - 72014 => true, - 72015 => true, - 72104 => true, - 72105 => true, - 72152 => true, - 72153 => true, - 72165 => true, - 72166 => true, - 72167 => true, - 72168 => true, - 72169 => true, - 72170 => true, - 72171 => true, - 72172 => true, - 72173 => true, - 72174 => true, - 72175 => true, - 72176 => true, - 72177 => true, - 72178 => true, - 72179 => true, - 72180 => true, - 72181 => true, - 72182 => true, - 72183 => true, - 72184 => true, - 72185 => true, - 72186 => true, - 72187 => true, - 72188 => true, - 72189 => true, - 72190 => true, - 72191 => true, - 72264 => true, - 72265 => true, - 72266 => true, - 72267 => true, - 72268 => true, - 72269 => true, - 72270 => true, - 72271 => true, - 72355 => true, - 72356 => true, - 72357 => true, - 72358 => true, - 72359 => true, - 72360 => true, - 72361 => true, - 72362 => true, - 72363 => true, - 72364 => true, - 72365 => true, - 72366 => true, - 72367 => true, - 72368 => true, - 72369 => true, - 72370 => true, - 72371 => true, - 72372 => true, - 72373 => true, - 72374 => true, - 72375 => true, - 72376 => true, - 72377 => true, - 72378 => true, - 72379 => true, - 72380 => true, - 72381 => true, - 72382 => true, - 72383 => true, - 72713 => true, - 72759 => true, - 72774 => true, - 72775 => true, - 72776 => true, - 72777 => true, - 72778 => true, - 72779 => true, - 72780 => true, - 72781 => true, - 72782 => true, - 72783 => true, - 72813 => true, - 72814 => true, - 72815 => true, - 72848 => true, - 72849 => true, - 72872 => true, - 72967 => true, - 72970 => true, - 73015 => true, - 73016 => true, - 73017 => true, - 73019 => true, - 73022 => true, - 73032 => true, - 73033 => true, - 73034 => true, - 73035 => true, - 73036 => true, - 73037 => true, - 73038 => true, - 73039 => true, - 73050 => true, - 73051 => true, - 73052 => true, - 73053 => true, - 73054 => true, - 73055 => true, - 73062 => true, - 73065 => true, - 73103 => true, - 73106 => true, - 73113 => true, - 73114 => true, - 73115 => true, - 73116 => true, - 73117 => true, - 73118 => true, - 73119 => true, - 73649 => true, - 73650 => true, - 73651 => true, - 73652 => true, - 73653 => true, - 73654 => true, - 73655 => true, - 73656 => true, - 73657 => true, - 73658 => true, - 73659 => true, - 73660 => true, - 73661 => true, - 73662 => true, - 73663 => true, - 73714 => true, - 73715 => true, - 73716 => true, - 73717 => true, - 73718 => true, - 73719 => true, - 73720 => true, - 73721 => true, - 73722 => true, - 73723 => true, - 73724 => true, - 73725 => true, - 73726 => true, - 74863 => true, - 74869 => true, - 74870 => true, - 74871 => true, - 74872 => true, - 74873 => true, - 74874 => true, - 74875 => true, - 74876 => true, - 74877 => true, - 74878 => true, - 74879 => true, - 78895 => true, - 78896 => true, - 78897 => true, - 78898 => true, - 78899 => true, - 78900 => true, - 78901 => true, - 78902 => true, - 78903 => true, - 78904 => true, - 92729 => true, - 92730 => true, - 92731 => true, - 92732 => true, - 92733 => true, - 92734 => true, - 92735 => true, - 92767 => true, - 92778 => true, - 92779 => true, - 92780 => true, - 92781 => true, - 92910 => true, - 92911 => true, - 92918 => true, - 92919 => true, - 92920 => true, - 92921 => true, - 92922 => true, - 92923 => true, - 92924 => true, - 92925 => true, - 92926 => true, - 92927 => true, - 92998 => true, - 92999 => true, - 93000 => true, - 93001 => true, - 93002 => true, - 93003 => true, - 93004 => true, - 93005 => true, - 93006 => true, - 93007 => true, - 93018 => true, - 93026 => true, - 93048 => true, - 93049 => true, - 93050 => true, - 93051 => true, - 93052 => true, - 94027 => true, - 94028 => true, - 94029 => true, - 94030 => true, - 94088 => true, - 94089 => true, - 94090 => true, - 94091 => true, - 94092 => true, - 94093 => true, - 94094 => true, - 94181 => true, - 94182 => true, - 94183 => true, - 94184 => true, - 94185 => true, - 94186 => true, - 94187 => true, - 94188 => true, - 94189 => true, - 94190 => true, - 94191 => true, - 94194 => true, - 94195 => true, - 94196 => true, - 94197 => true, - 94198 => true, - 94199 => true, - 94200 => true, - 94201 => true, - 94202 => true, - 94203 => true, - 94204 => true, - 94205 => true, - 94206 => true, - 94207 => true, - 100344 => true, - 100345 => true, - 100346 => true, - 100347 => true, - 100348 => true, - 100349 => true, - 100350 => true, - 100351 => true, - 110931 => true, - 110932 => true, - 110933 => true, - 110934 => true, - 110935 => true, - 110936 => true, - 110937 => true, - 110938 => true, - 110939 => true, - 110940 => true, - 110941 => true, - 110942 => true, - 110943 => true, - 110944 => true, - 110945 => true, - 110946 => true, - 110947 => true, - 110952 => true, - 110953 => true, - 110954 => true, - 110955 => true, - 110956 => true, - 110957 => true, - 110958 => true, - 110959 => true, - 113771 => true, - 113772 => true, - 113773 => true, - 113774 => true, - 113775 => true, - 113789 => true, - 113790 => true, - 113791 => true, - 113801 => true, - 113802 => true, - 113803 => true, - 113804 => true, - 113805 => true, - 113806 => true, - 113807 => true, - 113818 => true, - 113819 => true, - 119030 => true, - 119031 => true, - 119032 => true, - 119033 => true, - 119034 => true, - 119035 => true, - 119036 => true, - 119037 => true, - 119038 => true, - 119039 => true, - 119079 => true, - 119080 => true, - 119155 => true, - 119156 => true, - 119157 => true, - 119158 => true, - 119159 => true, - 119160 => true, - 119161 => true, - 119162 => true, - 119273 => true, - 119274 => true, - 119275 => true, - 119276 => true, - 119277 => true, - 119278 => true, - 119279 => true, - 119280 => true, - 119281 => true, - 119282 => true, - 119283 => true, - 119284 => true, - 119285 => true, - 119286 => true, - 119287 => true, - 119288 => true, - 119289 => true, - 119290 => true, - 119291 => true, - 119292 => true, - 119293 => true, - 119294 => true, - 119295 => true, - 119540 => true, - 119541 => true, - 119542 => true, - 119543 => true, - 119544 => true, - 119545 => true, - 119546 => true, - 119547 => true, - 119548 => true, - 119549 => true, - 119550 => true, - 119551 => true, - 119639 => true, - 119640 => true, - 119641 => true, - 119642 => true, - 119643 => true, - 119644 => true, - 119645 => true, - 119646 => true, - 119647 => true, - 119893 => true, - 119965 => true, - 119968 => true, - 119969 => true, - 119971 => true, - 119972 => true, - 119975 => true, - 119976 => true, - 119981 => true, - 119994 => true, - 119996 => true, - 120004 => true, - 120070 => true, - 120075 => true, - 120076 => true, - 120085 => true, - 120093 => true, - 120122 => true, - 120127 => true, - 120133 => true, - 120135 => true, - 120136 => true, - 120137 => true, - 120145 => true, - 120486 => true, - 120487 => true, - 120780 => true, - 120781 => true, - 121484 => true, - 121485 => true, - 121486 => true, - 121487 => true, - 121488 => true, - 121489 => true, - 121490 => true, - 121491 => true, - 121492 => true, - 121493 => true, - 121494 => true, - 121495 => true, - 121496 => true, - 121497 => true, - 121498 => true, - 121504 => true, - 122887 => true, - 122905 => true, - 122906 => true, - 122914 => true, - 122917 => true, - 123181 => true, - 123182 => true, - 123183 => true, - 123198 => true, - 123199 => true, - 123210 => true, - 123211 => true, - 123212 => true, - 123213 => true, - 123642 => true, - 123643 => true, - 123644 => true, - 123645 => true, - 123646 => true, - 125125 => true, - 125126 => true, - 125260 => true, - 125261 => true, - 125262 => true, - 125263 => true, - 125274 => true, - 125275 => true, - 125276 => true, - 125277 => true, - 126468 => true, - 126496 => true, - 126499 => true, - 126501 => true, - 126502 => true, - 126504 => true, - 126515 => true, - 126520 => true, - 126522 => true, - 126524 => true, - 126525 => true, - 126526 => true, - 126527 => true, - 126528 => true, - 126529 => true, - 126531 => true, - 126532 => true, - 126533 => true, - 126534 => true, - 126536 => true, - 126538 => true, - 126540 => true, - 126544 => true, - 126547 => true, - 126549 => true, - 126550 => true, - 126552 => true, - 126554 => true, - 126556 => true, - 126558 => true, - 126560 => true, - 126563 => true, - 126565 => true, - 126566 => true, - 126571 => true, - 126579 => true, - 126584 => true, - 126589 => true, - 126591 => true, - 126602 => true, - 126620 => true, - 126621 => true, - 126622 => true, - 126623 => true, - 126624 => true, - 126628 => true, - 126634 => true, - 127020 => true, - 127021 => true, - 127022 => true, - 127023 => true, - 127124 => true, - 127125 => true, - 127126 => true, - 127127 => true, - 127128 => true, - 127129 => true, - 127130 => true, - 127131 => true, - 127132 => true, - 127133 => true, - 127134 => true, - 127135 => true, - 127151 => true, - 127152 => true, - 127168 => true, - 127184 => true, - 127222 => true, - 127223 => true, - 127224 => true, - 127225 => true, - 127226 => true, - 127227 => true, - 127228 => true, - 127229 => true, - 127230 => true, - 127231 => true, - 127232 => true, - 127491 => true, - 127492 => true, - 127493 => true, - 127494 => true, - 127495 => true, - 127496 => true, - 127497 => true, - 127498 => true, - 127499 => true, - 127500 => true, - 127501 => true, - 127502 => true, - 127503 => true, - 127548 => true, - 127549 => true, - 127550 => true, - 127551 => true, - 127561 => true, - 127562 => true, - 127563 => true, - 127564 => true, - 127565 => true, - 127566 => true, - 127567 => true, - 127570 => true, - 127571 => true, - 127572 => true, - 127573 => true, - 127574 => true, - 127575 => true, - 127576 => true, - 127577 => true, - 127578 => true, - 127579 => true, - 127580 => true, - 127581 => true, - 127582 => true, - 127583 => true, - 128728 => true, - 128729 => true, - 128730 => true, - 128731 => true, - 128732 => true, - 128733 => true, - 128734 => true, - 128735 => true, - 128749 => true, - 128750 => true, - 128751 => true, - 128765 => true, - 128766 => true, - 128767 => true, - 128884 => true, - 128885 => true, - 128886 => true, - 128887 => true, - 128888 => true, - 128889 => true, - 128890 => true, - 128891 => true, - 128892 => true, - 128893 => true, - 128894 => true, - 128895 => true, - 128985 => true, - 128986 => true, - 128987 => true, - 128988 => true, - 128989 => true, - 128990 => true, - 128991 => true, - 129004 => true, - 129005 => true, - 129006 => true, - 129007 => true, - 129008 => true, - 129009 => true, - 129010 => true, - 129011 => true, - 129012 => true, - 129013 => true, - 129014 => true, - 129015 => true, - 129016 => true, - 129017 => true, - 129018 => true, - 129019 => true, - 129020 => true, - 129021 => true, - 129022 => true, - 129023 => true, - 129036 => true, - 129037 => true, - 129038 => true, - 129039 => true, - 129096 => true, - 129097 => true, - 129098 => true, - 129099 => true, - 129100 => true, - 129101 => true, - 129102 => true, - 129103 => true, - 129114 => true, - 129115 => true, - 129116 => true, - 129117 => true, - 129118 => true, - 129119 => true, - 129160 => true, - 129161 => true, - 129162 => true, - 129163 => true, - 129164 => true, - 129165 => true, - 129166 => true, - 129167 => true, - 129198 => true, - 129199 => true, - 129401 => true, - 129484 => true, - 129620 => true, - 129621 => true, - 129622 => true, - 129623 => true, - 129624 => true, - 129625 => true, - 129626 => true, - 129627 => true, - 129628 => true, - 129629 => true, - 129630 => true, - 129631 => true, - 129646 => true, - 129647 => true, - 129653 => true, - 129654 => true, - 129655 => true, - 129659 => true, - 129660 => true, - 129661 => true, - 129662 => true, - 129663 => true, - 129671 => true, - 129672 => true, - 129673 => true, - 129674 => true, - 129675 => true, - 129676 => true, - 129677 => true, - 129678 => true, - 129679 => true, - 129705 => true, - 129706 => true, - 129707 => true, - 129708 => true, - 129709 => true, - 129710 => true, - 129711 => true, - 129719 => true, - 129720 => true, - 129721 => true, - 129722 => true, - 129723 => true, - 129724 => true, - 129725 => true, - 129726 => true, - 129727 => true, - 129731 => true, - 129732 => true, - 129733 => true, - 129734 => true, - 129735 => true, - 129736 => true, - 129737 => true, - 129738 => true, - 129739 => true, - 129740 => true, - 129741 => true, - 129742 => true, - 129743 => true, - 129939 => true, - 131070 => true, - 131071 => true, - 177973 => true, - 177974 => true, - 177975 => true, - 177976 => true, - 177977 => true, - 177978 => true, - 177979 => true, - 177980 => true, - 177981 => true, - 177982 => true, - 177983 => true, - 178206 => true, - 178207 => true, - 183970 => true, - 183971 => true, - 183972 => true, - 183973 => true, - 183974 => true, - 183975 => true, - 183976 => true, - 183977 => true, - 183978 => true, - 183979 => true, - 183980 => true, - 183981 => true, - 183982 => true, - 183983 => true, - 194664 => true, - 194676 => true, - 194847 => true, - 194911 => true, - 195007 => true, - 196606 => true, - 196607 => true, - 262142 => true, - 262143 => true, - 327678 => true, - 327679 => true, - 393214 => true, - 393215 => true, - 458750 => true, - 458751 => true, - 524286 => true, - 524287 => true, - 589822 => true, - 589823 => true, - 655358 => true, - 655359 => true, - 720894 => true, - 720895 => true, - 786430 => true, - 786431 => true, - 851966 => true, - 851967 => true, - 917502 => true, - 917503 => true, - 917504 => true, - 917505 => true, - 917506 => true, - 917507 => true, - 917508 => true, - 917509 => true, - 917510 => true, - 917511 => true, - 917512 => true, - 917513 => true, - 917514 => true, - 917515 => true, - 917516 => true, - 917517 => true, - 917518 => true, - 917519 => true, - 917520 => true, - 917521 => true, - 917522 => true, - 917523 => true, - 917524 => true, - 917525 => true, - 917526 => true, - 917527 => true, - 917528 => true, - 917529 => true, - 917530 => true, - 917531 => true, - 917532 => true, - 917533 => true, - 917534 => true, - 917535 => true, - 983038 => true, - 983039 => true, - 1048574 => true, - 1048575 => true, - 1114110 => true, - 1114111 => true, -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php deleted file mode 100644 index 54f21cc0c..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php +++ /dev/null @@ -1,308 +0,0 @@ - ' ', - 168 => ' ̈', - 175 => ' ̄', - 180 => ' ́', - 184 => ' ̧', - 728 => ' ̆', - 729 => ' ̇', - 730 => ' ̊', - 731 => ' ̨', - 732 => ' ̃', - 733 => ' ̋', - 890 => ' ι', - 894 => ';', - 900 => ' ́', - 901 => ' ̈́', - 8125 => ' ̓', - 8127 => ' ̓', - 8128 => ' ͂', - 8129 => ' ̈͂', - 8141 => ' ̓̀', - 8142 => ' ̓́', - 8143 => ' ̓͂', - 8157 => ' ̔̀', - 8158 => ' ̔́', - 8159 => ' ̔͂', - 8173 => ' ̈̀', - 8174 => ' ̈́', - 8175 => '`', - 8189 => ' ́', - 8190 => ' ̔', - 8192 => ' ', - 8193 => ' ', - 8194 => ' ', - 8195 => ' ', - 8196 => ' ', - 8197 => ' ', - 8198 => ' ', - 8199 => ' ', - 8200 => ' ', - 8201 => ' ', - 8202 => ' ', - 8215 => ' ̳', - 8239 => ' ', - 8252 => '!!', - 8254 => ' ̅', - 8263 => '??', - 8264 => '?!', - 8265 => '!?', - 8287 => ' ', - 8314 => '+', - 8316 => '=', - 8317 => '(', - 8318 => ')', - 8330 => '+', - 8332 => '=', - 8333 => '(', - 8334 => ')', - 8448 => 'a/c', - 8449 => 'a/s', - 8453 => 'c/o', - 8454 => 'c/u', - 9332 => '(1)', - 9333 => '(2)', - 9334 => '(3)', - 9335 => '(4)', - 9336 => '(5)', - 9337 => '(6)', - 9338 => '(7)', - 9339 => '(8)', - 9340 => '(9)', - 9341 => '(10)', - 9342 => '(11)', - 9343 => '(12)', - 9344 => '(13)', - 9345 => '(14)', - 9346 => '(15)', - 9347 => '(16)', - 9348 => '(17)', - 9349 => '(18)', - 9350 => '(19)', - 9351 => '(20)', - 9372 => '(a)', - 9373 => '(b)', - 9374 => '(c)', - 9375 => '(d)', - 9376 => '(e)', - 9377 => '(f)', - 9378 => '(g)', - 9379 => '(h)', - 9380 => '(i)', - 9381 => '(j)', - 9382 => '(k)', - 9383 => '(l)', - 9384 => '(m)', - 9385 => '(n)', - 9386 => '(o)', - 9387 => '(p)', - 9388 => '(q)', - 9389 => '(r)', - 9390 => '(s)', - 9391 => '(t)', - 9392 => '(u)', - 9393 => '(v)', - 9394 => '(w)', - 9395 => '(x)', - 9396 => '(y)', - 9397 => '(z)', - 10868 => '::=', - 10869 => '==', - 10870 => '===', - 12288 => ' ', - 12443 => ' ゙', - 12444 => ' ゚', - 12800 => '(ᄀ)', - 12801 => '(ᄂ)', - 12802 => '(ᄃ)', - 12803 => '(ᄅ)', - 12804 => '(ᄆ)', - 12805 => '(ᄇ)', - 12806 => '(ᄉ)', - 12807 => '(ᄋ)', - 12808 => '(ᄌ)', - 12809 => '(ᄎ)', - 12810 => '(ᄏ)', - 12811 => '(ᄐ)', - 12812 => '(ᄑ)', - 12813 => '(ᄒ)', - 12814 => '(가)', - 12815 => '(나)', - 12816 => '(다)', - 12817 => '(라)', - 12818 => '(마)', - 12819 => '(바)', - 12820 => '(사)', - 12821 => '(아)', - 12822 => '(자)', - 12823 => '(차)', - 12824 => '(카)', - 12825 => '(타)', - 12826 => '(파)', - 12827 => '(하)', - 12828 => '(주)', - 12829 => '(오전)', - 12830 => '(오후)', - 12832 => '(一)', - 12833 => '(二)', - 12834 => '(三)', - 12835 => '(四)', - 12836 => '(五)', - 12837 => '(六)', - 12838 => '(七)', - 12839 => '(八)', - 12840 => '(九)', - 12841 => '(十)', - 12842 => '(月)', - 12843 => '(火)', - 12844 => '(水)', - 12845 => '(木)', - 12846 => '(金)', - 12847 => '(土)', - 12848 => '(日)', - 12849 => '(株)', - 12850 => '(有)', - 12851 => '(社)', - 12852 => '(名)', - 12853 => '(特)', - 12854 => '(財)', - 12855 => '(祝)', - 12856 => '(労)', - 12857 => '(代)', - 12858 => '(呼)', - 12859 => '(学)', - 12860 => '(監)', - 12861 => '(企)', - 12862 => '(資)', - 12863 => '(協)', - 12864 => '(祭)', - 12865 => '(休)', - 12866 => '(自)', - 12867 => '(至)', - 64297 => '+', - 64606 => ' ٌّ', - 64607 => ' ٍّ', - 64608 => ' َّ', - 64609 => ' ُّ', - 64610 => ' ِّ', - 64611 => ' ّٰ', - 65018 => 'صلى الله عليه وسلم', - 65019 => 'جل جلاله', - 65040 => ',', - 65043 => ':', - 65044 => ';', - 65045 => '!', - 65046 => '?', - 65075 => '_', - 65076 => '_', - 65077 => '(', - 65078 => ')', - 65079 => '{', - 65080 => '}', - 65095 => '[', - 65096 => ']', - 65097 => ' ̅', - 65098 => ' ̅', - 65099 => ' ̅', - 65100 => ' ̅', - 65101 => '_', - 65102 => '_', - 65103 => '_', - 65104 => ',', - 65108 => ';', - 65109 => ':', - 65110 => '?', - 65111 => '!', - 65113 => '(', - 65114 => ')', - 65115 => '{', - 65116 => '}', - 65119 => '#', - 65120 => '&', - 65121 => '*', - 65122 => '+', - 65124 => '<', - 65125 => '>', - 65126 => '=', - 65128 => '\\', - 65129 => '$', - 65130 => '%', - 65131 => '@', - 65136 => ' ً', - 65138 => ' ٌ', - 65140 => ' ٍ', - 65142 => ' َ', - 65144 => ' ُ', - 65146 => ' ِ', - 65148 => ' ّ', - 65150 => ' ْ', - 65281 => '!', - 65282 => '"', - 65283 => '#', - 65284 => '$', - 65285 => '%', - 65286 => '&', - 65287 => '\'', - 65288 => '(', - 65289 => ')', - 65290 => '*', - 65291 => '+', - 65292 => ',', - 65295 => '/', - 65306 => ':', - 65307 => ';', - 65308 => '<', - 65309 => '=', - 65310 => '>', - 65311 => '?', - 65312 => '@', - 65339 => '[', - 65340 => '\\', - 65341 => ']', - 65342 => '^', - 65343 => '_', - 65344 => '`', - 65371 => '{', - 65372 => '|', - 65373 => '}', - 65374 => '~', - 65507 => ' ̄', - 127233 => '0,', - 127234 => '1,', - 127235 => '2,', - 127236 => '3,', - 127237 => '4,', - 127238 => '5,', - 127239 => '6,', - 127240 => '7,', - 127241 => '8,', - 127242 => '9,', - 127248 => '(a)', - 127249 => '(b)', - 127250 => '(c)', - 127251 => '(d)', - 127252 => '(e)', - 127253 => '(f)', - 127254 => '(g)', - 127255 => '(h)', - 127256 => '(i)', - 127257 => '(j)', - 127258 => '(k)', - 127259 => '(l)', - 127260 => '(m)', - 127261 => '(n)', - 127262 => '(o)', - 127263 => '(p)', - 127264 => '(q)', - 127265 => '(r)', - 127266 => '(s)', - 127267 => '(t)', - 127268 => '(u)', - 127269 => '(v)', - 127270 => '(w)', - 127271 => '(x)', - 127272 => '(y)', - 127273 => '(z)', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php deleted file mode 100644 index 223396ec4..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php +++ /dev/null @@ -1,71 +0,0 @@ - true, - 1 => true, - 2 => true, - 3 => true, - 4 => true, - 5 => true, - 6 => true, - 7 => true, - 8 => true, - 9 => true, - 10 => true, - 11 => true, - 12 => true, - 13 => true, - 14 => true, - 15 => true, - 16 => true, - 17 => true, - 18 => true, - 19 => true, - 20 => true, - 21 => true, - 22 => true, - 23 => true, - 24 => true, - 25 => true, - 26 => true, - 27 => true, - 28 => true, - 29 => true, - 30 => true, - 31 => true, - 32 => true, - 33 => true, - 34 => true, - 35 => true, - 36 => true, - 37 => true, - 38 => true, - 39 => true, - 40 => true, - 41 => true, - 42 => true, - 43 => true, - 44 => true, - 47 => true, - 58 => true, - 59 => true, - 60 => true, - 61 => true, - 62 => true, - 63 => true, - 64 => true, - 91 => true, - 92 => true, - 93 => true, - 94 => true, - 95 => true, - 96 => true, - 123 => true, - 124 => true, - 125 => true, - 126 => true, - 127 => true, - 8800 => true, - 8814 => true, - 8815 => true, -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/ignored.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/ignored.php deleted file mode 100644 index b37784413..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/ignored.php +++ /dev/null @@ -1,273 +0,0 @@ - true, - 847 => true, - 6155 => true, - 6156 => true, - 6157 => true, - 8203 => true, - 8288 => true, - 8292 => true, - 65024 => true, - 65025 => true, - 65026 => true, - 65027 => true, - 65028 => true, - 65029 => true, - 65030 => true, - 65031 => true, - 65032 => true, - 65033 => true, - 65034 => true, - 65035 => true, - 65036 => true, - 65037 => true, - 65038 => true, - 65039 => true, - 65279 => true, - 113824 => true, - 113825 => true, - 113826 => true, - 113827 => true, - 917760 => true, - 917761 => true, - 917762 => true, - 917763 => true, - 917764 => true, - 917765 => true, - 917766 => true, - 917767 => true, - 917768 => true, - 917769 => true, - 917770 => true, - 917771 => true, - 917772 => true, - 917773 => true, - 917774 => true, - 917775 => true, - 917776 => true, - 917777 => true, - 917778 => true, - 917779 => true, - 917780 => true, - 917781 => true, - 917782 => true, - 917783 => true, - 917784 => true, - 917785 => true, - 917786 => true, - 917787 => true, - 917788 => true, - 917789 => true, - 917790 => true, - 917791 => true, - 917792 => true, - 917793 => true, - 917794 => true, - 917795 => true, - 917796 => true, - 917797 => true, - 917798 => true, - 917799 => true, - 917800 => true, - 917801 => true, - 917802 => true, - 917803 => true, - 917804 => true, - 917805 => true, - 917806 => true, - 917807 => true, - 917808 => true, - 917809 => true, - 917810 => true, - 917811 => true, - 917812 => true, - 917813 => true, - 917814 => true, - 917815 => true, - 917816 => true, - 917817 => true, - 917818 => true, - 917819 => true, - 917820 => true, - 917821 => true, - 917822 => true, - 917823 => true, - 917824 => true, - 917825 => true, - 917826 => true, - 917827 => true, - 917828 => true, - 917829 => true, - 917830 => true, - 917831 => true, - 917832 => true, - 917833 => true, - 917834 => true, - 917835 => true, - 917836 => true, - 917837 => true, - 917838 => true, - 917839 => true, - 917840 => true, - 917841 => true, - 917842 => true, - 917843 => true, - 917844 => true, - 917845 => true, - 917846 => true, - 917847 => true, - 917848 => true, - 917849 => true, - 917850 => true, - 917851 => true, - 917852 => true, - 917853 => true, - 917854 => true, - 917855 => true, - 917856 => true, - 917857 => true, - 917858 => true, - 917859 => true, - 917860 => true, - 917861 => true, - 917862 => true, - 917863 => true, - 917864 => true, - 917865 => true, - 917866 => true, - 917867 => true, - 917868 => true, - 917869 => true, - 917870 => true, - 917871 => true, - 917872 => true, - 917873 => true, - 917874 => true, - 917875 => true, - 917876 => true, - 917877 => true, - 917878 => true, - 917879 => true, - 917880 => true, - 917881 => true, - 917882 => true, - 917883 => true, - 917884 => true, - 917885 => true, - 917886 => true, - 917887 => true, - 917888 => true, - 917889 => true, - 917890 => true, - 917891 => true, - 917892 => true, - 917893 => true, - 917894 => true, - 917895 => true, - 917896 => true, - 917897 => true, - 917898 => true, - 917899 => true, - 917900 => true, - 917901 => true, - 917902 => true, - 917903 => true, - 917904 => true, - 917905 => true, - 917906 => true, - 917907 => true, - 917908 => true, - 917909 => true, - 917910 => true, - 917911 => true, - 917912 => true, - 917913 => true, - 917914 => true, - 917915 => true, - 917916 => true, - 917917 => true, - 917918 => true, - 917919 => true, - 917920 => true, - 917921 => true, - 917922 => true, - 917923 => true, - 917924 => true, - 917925 => true, - 917926 => true, - 917927 => true, - 917928 => true, - 917929 => true, - 917930 => true, - 917931 => true, - 917932 => true, - 917933 => true, - 917934 => true, - 917935 => true, - 917936 => true, - 917937 => true, - 917938 => true, - 917939 => true, - 917940 => true, - 917941 => true, - 917942 => true, - 917943 => true, - 917944 => true, - 917945 => true, - 917946 => true, - 917947 => true, - 917948 => true, - 917949 => true, - 917950 => true, - 917951 => true, - 917952 => true, - 917953 => true, - 917954 => true, - 917955 => true, - 917956 => true, - 917957 => true, - 917958 => true, - 917959 => true, - 917960 => true, - 917961 => true, - 917962 => true, - 917963 => true, - 917964 => true, - 917965 => true, - 917966 => true, - 917967 => true, - 917968 => true, - 917969 => true, - 917970 => true, - 917971 => true, - 917972 => true, - 917973 => true, - 917974 => true, - 917975 => true, - 917976 => true, - 917977 => true, - 917978 => true, - 917979 => true, - 917980 => true, - 917981 => true, - 917982 => true, - 917983 => true, - 917984 => true, - 917985 => true, - 917986 => true, - 917987 => true, - 917988 => true, - 917989 => true, - 917990 => true, - 917991 => true, - 917992 => true, - 917993 => true, - 917994 => true, - 917995 => true, - 917996 => true, - 917997 => true, - 917998 => true, - 917999 => true, -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/mapped.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/mapped.php deleted file mode 100644 index 9b85fe9d3..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/mapped.php +++ /dev/null @@ -1,5778 +0,0 @@ - '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', - 170 => 'a', - 178 => '2', - 179 => '3', - 181 => 'μ', - 185 => '1', - 186 => 'o', - 188 => '1⁄4', - 189 => '1⁄2', - 190 => '3⁄4', - 192 => 'à', - 193 => 'á', - 194 => 'â', - 195 => 'ã', - 196 => 'ä', - 197 => 'å', - 198 => 'æ', - 199 => 'ç', - 200 => 'è', - 201 => 'é', - 202 => 'ê', - 203 => 'ë', - 204 => 'ì', - 205 => 'í', - 206 => 'î', - 207 => 'ï', - 208 => 'ð', - 209 => 'ñ', - 210 => 'ò', - 211 => 'ó', - 212 => 'ô', - 213 => 'õ', - 214 => 'ö', - 216 => 'ø', - 217 => 'ù', - 218 => 'ú', - 219 => 'û', - 220 => 'ü', - 221 => 'ý', - 222 => 'þ', - 256 => 'ā', - 258 => 'ă', - 260 => 'ą', - 262 => 'ć', - 264 => 'ĉ', - 266 => 'ċ', - 268 => 'č', - 270 => 'ď', - 272 => 'đ', - 274 => 'ē', - 276 => 'ĕ', - 278 => 'ė', - 280 => 'ę', - 282 => 'ě', - 284 => 'ĝ', - 286 => 'ğ', - 288 => 'ġ', - 290 => 'ģ', - 292 => 'ĥ', - 294 => 'ħ', - 296 => 'ĩ', - 298 => 'ī', - 300 => 'ĭ', - 302 => 'į', - 304 => 'i̇', - 306 => 'ij', - 307 => 'ij', - 308 => 'ĵ', - 310 => 'ķ', - 313 => 'ĺ', - 315 => 'ļ', - 317 => 'ľ', - 319 => 'l·', - 320 => 'l·', - 321 => 'ł', - 323 => 'ń', - 325 => 'ņ', - 327 => 'ň', - 329 => 'ʼn', - 330 => 'ŋ', - 332 => 'ō', - 334 => 'ŏ', - 336 => 'ő', - 338 => 'œ', - 340 => 'ŕ', - 342 => 'ŗ', - 344 => 'ř', - 346 => 'ś', - 348 => 'ŝ', - 350 => 'ş', - 352 => 'š', - 354 => 'ţ', - 356 => 'ť', - 358 => 'ŧ', - 360 => 'ũ', - 362 => 'ū', - 364 => 'ŭ', - 366 => 'ů', - 368 => 'ű', - 370 => 'ų', - 372 => 'ŵ', - 374 => 'ŷ', - 376 => 'ÿ', - 377 => 'ź', - 379 => 'ż', - 381 => 'ž', - 383 => 's', - 385 => 'ɓ', - 386 => 'ƃ', - 388 => 'ƅ', - 390 => 'ɔ', - 391 => 'ƈ', - 393 => 'ɖ', - 394 => 'ɗ', - 395 => 'ƌ', - 398 => 'ǝ', - 399 => 'ə', - 400 => 'ɛ', - 401 => 'ƒ', - 403 => 'ɠ', - 404 => 'ɣ', - 406 => 'ɩ', - 407 => 'ɨ', - 408 => 'ƙ', - 412 => 'ɯ', - 413 => 'ɲ', - 415 => 'ɵ', - 416 => 'ơ', - 418 => 'ƣ', - 420 => 'ƥ', - 422 => 'ʀ', - 423 => 'ƨ', - 425 => 'ʃ', - 428 => 'ƭ', - 430 => 'ʈ', - 431 => 'ư', - 433 => 'ʊ', - 434 => 'ʋ', - 435 => 'ƴ', - 437 => 'ƶ', - 439 => 'ʒ', - 440 => 'ƹ', - 444 => 'ƽ', - 452 => 'dž', - 453 => 'dž', - 454 => 'dž', - 455 => 'lj', - 456 => 'lj', - 457 => 'lj', - 458 => 'nj', - 459 => 'nj', - 460 => 'nj', - 461 => 'ǎ', - 463 => 'ǐ', - 465 => 'ǒ', - 467 => 'ǔ', - 469 => 'ǖ', - 471 => 'ǘ', - 473 => 'ǚ', - 475 => 'ǜ', - 478 => 'ǟ', - 480 => 'ǡ', - 482 => 'ǣ', - 484 => 'ǥ', - 486 => 'ǧ', - 488 => 'ǩ', - 490 => 'ǫ', - 492 => 'ǭ', - 494 => 'ǯ', - 497 => 'dz', - 498 => 'dz', - 499 => 'dz', - 500 => 'ǵ', - 502 => 'ƕ', - 503 => 'ƿ', - 504 => 'ǹ', - 506 => 'ǻ', - 508 => 'ǽ', - 510 => 'ǿ', - 512 => 'ȁ', - 514 => 'ȃ', - 516 => 'ȅ', - 518 => 'ȇ', - 520 => 'ȉ', - 522 => 'ȋ', - 524 => 'ȍ', - 526 => 'ȏ', - 528 => 'ȑ', - 530 => 'ȓ', - 532 => 'ȕ', - 534 => 'ȗ', - 536 => 'ș', - 538 => 'ț', - 540 => 'ȝ', - 542 => 'ȟ', - 544 => 'ƞ', - 546 => 'ȣ', - 548 => 'ȥ', - 550 => 'ȧ', - 552 => 'ȩ', - 554 => 'ȫ', - 556 => 'ȭ', - 558 => 'ȯ', - 560 => 'ȱ', - 562 => 'ȳ', - 570 => 'ⱥ', - 571 => 'ȼ', - 573 => 'ƚ', - 574 => 'ⱦ', - 577 => 'ɂ', - 579 => 'ƀ', - 580 => 'ʉ', - 581 => 'ʌ', - 582 => 'ɇ', - 584 => 'ɉ', - 586 => 'ɋ', - 588 => 'ɍ', - 590 => 'ɏ', - 688 => 'h', - 689 => 'ɦ', - 690 => 'j', - 691 => 'r', - 692 => 'ɹ', - 693 => 'ɻ', - 694 => 'ʁ', - 695 => 'w', - 696 => 'y', - 736 => 'ɣ', - 737 => 'l', - 738 => 's', - 739 => 'x', - 740 => 'ʕ', - 832 => '̀', - 833 => '́', - 835 => '̓', - 836 => '̈́', - 837 => 'ι', - 880 => 'ͱ', - 882 => 'ͳ', - 884 => 'ʹ', - 886 => 'ͷ', - 895 => 'ϳ', - 902 => 'ά', - 903 => '·', - 904 => 'έ', - 905 => 'ή', - 906 => 'ί', - 908 => 'ό', - 910 => 'ύ', - 911 => 'ώ', - 913 => 'α', - 914 => 'β', - 915 => 'γ', - 916 => 'δ', - 917 => 'ε', - 918 => 'ζ', - 919 => 'η', - 920 => 'θ', - 921 => 'ι', - 922 => 'κ', - 923 => 'λ', - 924 => 'μ', - 925 => 'ν', - 926 => 'ξ', - 927 => 'ο', - 928 => 'π', - 929 => 'ρ', - 931 => 'σ', - 932 => 'τ', - 933 => 'υ', - 934 => 'φ', - 935 => 'χ', - 936 => 'ψ', - 937 => 'ω', - 938 => 'ϊ', - 939 => 'ϋ', - 975 => 'ϗ', - 976 => 'β', - 977 => 'θ', - 978 => 'υ', - 979 => 'ύ', - 980 => 'ϋ', - 981 => 'φ', - 982 => 'π', - 984 => 'ϙ', - 986 => 'ϛ', - 988 => 'ϝ', - 990 => 'ϟ', - 992 => 'ϡ', - 994 => 'ϣ', - 996 => 'ϥ', - 998 => 'ϧ', - 1000 => 'ϩ', - 1002 => 'ϫ', - 1004 => 'ϭ', - 1006 => 'ϯ', - 1008 => 'κ', - 1009 => 'ρ', - 1010 => 'σ', - 1012 => 'θ', - 1013 => 'ε', - 1015 => 'ϸ', - 1017 => 'σ', - 1018 => 'ϻ', - 1021 => 'ͻ', - 1022 => 'ͼ', - 1023 => 'ͽ', - 1024 => 'ѐ', - 1025 => 'ё', - 1026 => 'ђ', - 1027 => 'ѓ', - 1028 => 'є', - 1029 => 'ѕ', - 1030 => 'і', - 1031 => 'ї', - 1032 => 'ј', - 1033 => 'љ', - 1034 => 'њ', - 1035 => 'ћ', - 1036 => 'ќ', - 1037 => 'ѝ', - 1038 => 'ў', - 1039 => 'џ', - 1040 => 'а', - 1041 => 'б', - 1042 => 'в', - 1043 => 'г', - 1044 => 'д', - 1045 => 'е', - 1046 => 'ж', - 1047 => 'з', - 1048 => 'и', - 1049 => 'й', - 1050 => 'к', - 1051 => 'л', - 1052 => 'м', - 1053 => 'н', - 1054 => 'о', - 1055 => 'п', - 1056 => 'р', - 1057 => 'с', - 1058 => 'т', - 1059 => 'у', - 1060 => 'ф', - 1061 => 'х', - 1062 => 'ц', - 1063 => 'ч', - 1064 => 'ш', - 1065 => 'щ', - 1066 => 'ъ', - 1067 => 'ы', - 1068 => 'ь', - 1069 => 'э', - 1070 => 'ю', - 1071 => 'я', - 1120 => 'ѡ', - 1122 => 'ѣ', - 1124 => 'ѥ', - 1126 => 'ѧ', - 1128 => 'ѩ', - 1130 => 'ѫ', - 1132 => 'ѭ', - 1134 => 'ѯ', - 1136 => 'ѱ', - 1138 => 'ѳ', - 1140 => 'ѵ', - 1142 => 'ѷ', - 1144 => 'ѹ', - 1146 => 'ѻ', - 1148 => 'ѽ', - 1150 => 'ѿ', - 1152 => 'ҁ', - 1162 => 'ҋ', - 1164 => 'ҍ', - 1166 => 'ҏ', - 1168 => 'ґ', - 1170 => 'ғ', - 1172 => 'ҕ', - 1174 => 'җ', - 1176 => 'ҙ', - 1178 => 'қ', - 1180 => 'ҝ', - 1182 => 'ҟ', - 1184 => 'ҡ', - 1186 => 'ң', - 1188 => 'ҥ', - 1190 => 'ҧ', - 1192 => 'ҩ', - 1194 => 'ҫ', - 1196 => 'ҭ', - 1198 => 'ү', - 1200 => 'ұ', - 1202 => 'ҳ', - 1204 => 'ҵ', - 1206 => 'ҷ', - 1208 => 'ҹ', - 1210 => 'һ', - 1212 => 'ҽ', - 1214 => 'ҿ', - 1217 => 'ӂ', - 1219 => 'ӄ', - 1221 => 'ӆ', - 1223 => 'ӈ', - 1225 => 'ӊ', - 1227 => 'ӌ', - 1229 => 'ӎ', - 1232 => 'ӑ', - 1234 => 'ӓ', - 1236 => 'ӕ', - 1238 => 'ӗ', - 1240 => 'ә', - 1242 => 'ӛ', - 1244 => 'ӝ', - 1246 => 'ӟ', - 1248 => 'ӡ', - 1250 => 'ӣ', - 1252 => 'ӥ', - 1254 => 'ӧ', - 1256 => 'ө', - 1258 => 'ӫ', - 1260 => 'ӭ', - 1262 => 'ӯ', - 1264 => 'ӱ', - 1266 => 'ӳ', - 1268 => 'ӵ', - 1270 => 'ӷ', - 1272 => 'ӹ', - 1274 => 'ӻ', - 1276 => 'ӽ', - 1278 => 'ӿ', - 1280 => 'ԁ', - 1282 => 'ԃ', - 1284 => 'ԅ', - 1286 => 'ԇ', - 1288 => 'ԉ', - 1290 => 'ԋ', - 1292 => 'ԍ', - 1294 => 'ԏ', - 1296 => 'ԑ', - 1298 => 'ԓ', - 1300 => 'ԕ', - 1302 => 'ԗ', - 1304 => 'ԙ', - 1306 => 'ԛ', - 1308 => 'ԝ', - 1310 => 'ԟ', - 1312 => 'ԡ', - 1314 => 'ԣ', - 1316 => 'ԥ', - 1318 => 'ԧ', - 1320 => 'ԩ', - 1322 => 'ԫ', - 1324 => 'ԭ', - 1326 => 'ԯ', - 1329 => 'ա', - 1330 => 'բ', - 1331 => 'գ', - 1332 => 'դ', - 1333 => 'ե', - 1334 => 'զ', - 1335 => 'է', - 1336 => 'ը', - 1337 => 'թ', - 1338 => 'ժ', - 1339 => 'ի', - 1340 => 'լ', - 1341 => 'խ', - 1342 => 'ծ', - 1343 => 'կ', - 1344 => 'հ', - 1345 => 'ձ', - 1346 => 'ղ', - 1347 => 'ճ', - 1348 => 'մ', - 1349 => 'յ', - 1350 => 'ն', - 1351 => 'շ', - 1352 => 'ո', - 1353 => 'չ', - 1354 => 'պ', - 1355 => 'ջ', - 1356 => 'ռ', - 1357 => 'ս', - 1358 => 'վ', - 1359 => 'տ', - 1360 => 'ր', - 1361 => 'ց', - 1362 => 'ւ', - 1363 => 'փ', - 1364 => 'ք', - 1365 => 'օ', - 1366 => 'ֆ', - 1415 => 'եւ', - 1653 => 'اٴ', - 1654 => 'وٴ', - 1655 => 'ۇٴ', - 1656 => 'يٴ', - 2392 => 'क़', - 2393 => 'ख़', - 2394 => 'ग़', - 2395 => 'ज़', - 2396 => 'ड़', - 2397 => 'ढ़', - 2398 => 'फ़', - 2399 => 'य़', - 2524 => 'ড়', - 2525 => 'ঢ়', - 2527 => 'য়', - 2611 => 'ਲ਼', - 2614 => 'ਸ਼', - 2649 => 'ਖ਼', - 2650 => 'ਗ਼', - 2651 => 'ਜ਼', - 2654 => 'ਫ਼', - 2908 => 'ଡ଼', - 2909 => 'ଢ଼', - 3635 => 'ํา', - 3763 => 'ໍາ', - 3804 => 'ຫນ', - 3805 => 'ຫມ', - 3852 => '་', - 3907 => 'གྷ', - 3917 => 'ཌྷ', - 3922 => 'དྷ', - 3927 => 'བྷ', - 3932 => 'ཛྷ', - 3945 => 'ཀྵ', - 3955 => 'ཱི', - 3957 => 'ཱུ', - 3958 => 'ྲྀ', - 3959 => 'ྲཱྀ', - 3960 => 'ླྀ', - 3961 => 'ླཱྀ', - 3969 => 'ཱྀ', - 3987 => 'ྒྷ', - 3997 => 'ྜྷ', - 4002 => 'ྡྷ', - 4007 => 'ྦྷ', - 4012 => 'ྫྷ', - 4025 => 'ྐྵ', - 4295 => 'ⴧ', - 4301 => 'ⴭ', - 4348 => 'ნ', - 5112 => 'Ᏸ', - 5113 => 'Ᏹ', - 5114 => 'Ᏺ', - 5115 => 'Ᏻ', - 5116 => 'Ᏼ', - 5117 => 'Ᏽ', - 7296 => 'в', - 7297 => 'д', - 7298 => 'о', - 7299 => 'с', - 7300 => 'т', - 7301 => 'т', - 7302 => 'ъ', - 7303 => 'ѣ', - 7304 => 'ꙋ', - 7312 => 'ა', - 7313 => 'ბ', - 7314 => 'გ', - 7315 => 'დ', - 7316 => 'ე', - 7317 => 'ვ', - 7318 => 'ზ', - 7319 => 'თ', - 7320 => 'ი', - 7321 => 'კ', - 7322 => 'ლ', - 7323 => 'მ', - 7324 => 'ნ', - 7325 => 'ო', - 7326 => 'პ', - 7327 => 'ჟ', - 7328 => 'რ', - 7329 => 'ს', - 7330 => 'ტ', - 7331 => 'უ', - 7332 => 'ფ', - 7333 => 'ქ', - 7334 => 'ღ', - 7335 => 'ყ', - 7336 => 'შ', - 7337 => 'ჩ', - 7338 => 'ც', - 7339 => 'ძ', - 7340 => 'წ', - 7341 => 'ჭ', - 7342 => 'ხ', - 7343 => 'ჯ', - 7344 => 'ჰ', - 7345 => 'ჱ', - 7346 => 'ჲ', - 7347 => 'ჳ', - 7348 => 'ჴ', - 7349 => 'ჵ', - 7350 => 'ჶ', - 7351 => 'ჷ', - 7352 => 'ჸ', - 7353 => 'ჹ', - 7354 => 'ჺ', - 7357 => 'ჽ', - 7358 => 'ჾ', - 7359 => 'ჿ', - 7468 => 'a', - 7469 => 'æ', - 7470 => 'b', - 7472 => 'd', - 7473 => 'e', - 7474 => 'ǝ', - 7475 => 'g', - 7476 => 'h', - 7477 => 'i', - 7478 => 'j', - 7479 => 'k', - 7480 => 'l', - 7481 => 'm', - 7482 => 'n', - 7484 => 'o', - 7485 => 'ȣ', - 7486 => 'p', - 7487 => 'r', - 7488 => 't', - 7489 => 'u', - 7490 => 'w', - 7491 => 'a', - 7492 => 'ɐ', - 7493 => 'ɑ', - 7494 => 'ᴂ', - 7495 => 'b', - 7496 => 'd', - 7497 => 'e', - 7498 => 'ə', - 7499 => 'ɛ', - 7500 => 'ɜ', - 7501 => 'g', - 7503 => 'k', - 7504 => 'm', - 7505 => 'ŋ', - 7506 => 'o', - 7507 => 'ɔ', - 7508 => 'ᴖ', - 7509 => 'ᴗ', - 7510 => 'p', - 7511 => 't', - 7512 => 'u', - 7513 => 'ᴝ', - 7514 => 'ɯ', - 7515 => 'v', - 7516 => 'ᴥ', - 7517 => 'β', - 7518 => 'γ', - 7519 => 'δ', - 7520 => 'φ', - 7521 => 'χ', - 7522 => 'i', - 7523 => 'r', - 7524 => 'u', - 7525 => 'v', - 7526 => 'β', - 7527 => 'γ', - 7528 => 'ρ', - 7529 => 'φ', - 7530 => 'χ', - 7544 => 'н', - 7579 => 'ɒ', - 7580 => 'c', - 7581 => 'ɕ', - 7582 => 'ð', - 7583 => 'ɜ', - 7584 => 'f', - 7585 => 'ɟ', - 7586 => 'ɡ', - 7587 => 'ɥ', - 7588 => 'ɨ', - 7589 => 'ɩ', - 7590 => 'ɪ', - 7591 => 'ᵻ', - 7592 => 'ʝ', - 7593 => 'ɭ', - 7594 => 'ᶅ', - 7595 => 'ʟ', - 7596 => 'ɱ', - 7597 => 'ɰ', - 7598 => 'ɲ', - 7599 => 'ɳ', - 7600 => 'ɴ', - 7601 => 'ɵ', - 7602 => 'ɸ', - 7603 => 'ʂ', - 7604 => 'ʃ', - 7605 => 'ƫ', - 7606 => 'ʉ', - 7607 => 'ʊ', - 7608 => 'ᴜ', - 7609 => 'ʋ', - 7610 => 'ʌ', - 7611 => 'z', - 7612 => 'ʐ', - 7613 => 'ʑ', - 7614 => 'ʒ', - 7615 => 'θ', - 7680 => 'ḁ', - 7682 => 'ḃ', - 7684 => 'ḅ', - 7686 => 'ḇ', - 7688 => 'ḉ', - 7690 => 'ḋ', - 7692 => 'ḍ', - 7694 => 'ḏ', - 7696 => 'ḑ', - 7698 => 'ḓ', - 7700 => 'ḕ', - 7702 => 'ḗ', - 7704 => 'ḙ', - 7706 => 'ḛ', - 7708 => 'ḝ', - 7710 => 'ḟ', - 7712 => 'ḡ', - 7714 => 'ḣ', - 7716 => 'ḥ', - 7718 => 'ḧ', - 7720 => 'ḩ', - 7722 => 'ḫ', - 7724 => 'ḭ', - 7726 => 'ḯ', - 7728 => 'ḱ', - 7730 => 'ḳ', - 7732 => 'ḵ', - 7734 => 'ḷ', - 7736 => 'ḹ', - 7738 => 'ḻ', - 7740 => 'ḽ', - 7742 => 'ḿ', - 7744 => 'ṁ', - 7746 => 'ṃ', - 7748 => 'ṅ', - 7750 => 'ṇ', - 7752 => 'ṉ', - 7754 => 'ṋ', - 7756 => 'ṍ', - 7758 => 'ṏ', - 7760 => 'ṑ', - 7762 => 'ṓ', - 7764 => 'ṕ', - 7766 => 'ṗ', - 7768 => 'ṙ', - 7770 => 'ṛ', - 7772 => 'ṝ', - 7774 => 'ṟ', - 7776 => 'ṡ', - 7778 => 'ṣ', - 7780 => 'ṥ', - 7782 => 'ṧ', - 7784 => 'ṩ', - 7786 => 'ṫ', - 7788 => 'ṭ', - 7790 => 'ṯ', - 7792 => 'ṱ', - 7794 => 'ṳ', - 7796 => 'ṵ', - 7798 => 'ṷ', - 7800 => 'ṹ', - 7802 => 'ṻ', - 7804 => 'ṽ', - 7806 => 'ṿ', - 7808 => 'ẁ', - 7810 => 'ẃ', - 7812 => 'ẅ', - 7814 => 'ẇ', - 7816 => 'ẉ', - 7818 => 'ẋ', - 7820 => 'ẍ', - 7822 => 'ẏ', - 7824 => 'ẑ', - 7826 => 'ẓ', - 7828 => 'ẕ', - 7834 => 'aʾ', - 7835 => 'ṡ', - 7838 => 'ss', - 7840 => 'ạ', - 7842 => 'ả', - 7844 => 'ấ', - 7846 => 'ầ', - 7848 => 'ẩ', - 7850 => 'ẫ', - 7852 => 'ậ', - 7854 => 'ắ', - 7856 => 'ằ', - 7858 => 'ẳ', - 7860 => 'ẵ', - 7862 => 'ặ', - 7864 => 'ẹ', - 7866 => 'ẻ', - 7868 => 'ẽ', - 7870 => 'ế', - 7872 => 'ề', - 7874 => 'ể', - 7876 => 'ễ', - 7878 => 'ệ', - 7880 => 'ỉ', - 7882 => 'ị', - 7884 => 'ọ', - 7886 => 'ỏ', - 7888 => 'ố', - 7890 => 'ồ', - 7892 => 'ổ', - 7894 => 'ỗ', - 7896 => 'ộ', - 7898 => 'ớ', - 7900 => 'ờ', - 7902 => 'ở', - 7904 => 'ỡ', - 7906 => 'ợ', - 7908 => 'ụ', - 7910 => 'ủ', - 7912 => 'ứ', - 7914 => 'ừ', - 7916 => 'ử', - 7918 => 'ữ', - 7920 => 'ự', - 7922 => 'ỳ', - 7924 => 'ỵ', - 7926 => 'ỷ', - 7928 => 'ỹ', - 7930 => 'ỻ', - 7932 => 'ỽ', - 7934 => 'ỿ', - 7944 => 'ἀ', - 7945 => 'ἁ', - 7946 => 'ἂ', - 7947 => 'ἃ', - 7948 => 'ἄ', - 7949 => 'ἅ', - 7950 => 'ἆ', - 7951 => 'ἇ', - 7960 => 'ἐ', - 7961 => 'ἑ', - 7962 => 'ἒ', - 7963 => 'ἓ', - 7964 => 'ἔ', - 7965 => 'ἕ', - 7976 => 'ἠ', - 7977 => 'ἡ', - 7978 => 'ἢ', - 7979 => 'ἣ', - 7980 => 'ἤ', - 7981 => 'ἥ', - 7982 => 'ἦ', - 7983 => 'ἧ', - 7992 => 'ἰ', - 7993 => 'ἱ', - 7994 => 'ἲ', - 7995 => 'ἳ', - 7996 => 'ἴ', - 7997 => 'ἵ', - 7998 => 'ἶ', - 7999 => 'ἷ', - 8008 => 'ὀ', - 8009 => 'ὁ', - 8010 => 'ὂ', - 8011 => 'ὃ', - 8012 => 'ὄ', - 8013 => 'ὅ', - 8025 => 'ὑ', - 8027 => 'ὓ', - 8029 => 'ὕ', - 8031 => 'ὗ', - 8040 => 'ὠ', - 8041 => 'ὡ', - 8042 => 'ὢ', - 8043 => 'ὣ', - 8044 => 'ὤ', - 8045 => 'ὥ', - 8046 => 'ὦ', - 8047 => 'ὧ', - 8049 => 'ά', - 8051 => 'έ', - 8053 => 'ή', - 8055 => 'ί', - 8057 => 'ό', - 8059 => 'ύ', - 8061 => 'ώ', - 8064 => 'ἀι', - 8065 => 'ἁι', - 8066 => 'ἂι', - 8067 => 'ἃι', - 8068 => 'ἄι', - 8069 => 'ἅι', - 8070 => 'ἆι', - 8071 => 'ἇι', - 8072 => 'ἀι', - 8073 => 'ἁι', - 8074 => 'ἂι', - 8075 => 'ἃι', - 8076 => 'ἄι', - 8077 => 'ἅι', - 8078 => 'ἆι', - 8079 => 'ἇι', - 8080 => 'ἠι', - 8081 => 'ἡι', - 8082 => 'ἢι', - 8083 => 'ἣι', - 8084 => 'ἤι', - 8085 => 'ἥι', - 8086 => 'ἦι', - 8087 => 'ἧι', - 8088 => 'ἠι', - 8089 => 'ἡι', - 8090 => 'ἢι', - 8091 => 'ἣι', - 8092 => 'ἤι', - 8093 => 'ἥι', - 8094 => 'ἦι', - 8095 => 'ἧι', - 8096 => 'ὠι', - 8097 => 'ὡι', - 8098 => 'ὢι', - 8099 => 'ὣι', - 8100 => 'ὤι', - 8101 => 'ὥι', - 8102 => 'ὦι', - 8103 => 'ὧι', - 8104 => 'ὠι', - 8105 => 'ὡι', - 8106 => 'ὢι', - 8107 => 'ὣι', - 8108 => 'ὤι', - 8109 => 'ὥι', - 8110 => 'ὦι', - 8111 => 'ὧι', - 8114 => 'ὰι', - 8115 => 'αι', - 8116 => 'άι', - 8119 => 'ᾶι', - 8120 => 'ᾰ', - 8121 => 'ᾱ', - 8122 => 'ὰ', - 8123 => 'ά', - 8124 => 'αι', - 8126 => 'ι', - 8130 => 'ὴι', - 8131 => 'ηι', - 8132 => 'ήι', - 8135 => 'ῆι', - 8136 => 'ὲ', - 8137 => 'έ', - 8138 => 'ὴ', - 8139 => 'ή', - 8140 => 'ηι', - 8147 => 'ΐ', - 8152 => 'ῐ', - 8153 => 'ῑ', - 8154 => 'ὶ', - 8155 => 'ί', - 8163 => 'ΰ', - 8168 => 'ῠ', - 8169 => 'ῡ', - 8170 => 'ὺ', - 8171 => 'ύ', - 8172 => 'ῥ', - 8178 => 'ὼι', - 8179 => 'ωι', - 8180 => 'ώι', - 8183 => 'ῶι', - 8184 => 'ὸ', - 8185 => 'ό', - 8186 => 'ὼ', - 8187 => 'ώ', - 8188 => 'ωι', - 8209 => '‐', - 8243 => '′′', - 8244 => '′′′', - 8246 => '‵‵', - 8247 => '‵‵‵', - 8279 => '′′′′', - 8304 => '0', - 8305 => 'i', - 8308 => '4', - 8309 => '5', - 8310 => '6', - 8311 => '7', - 8312 => '8', - 8313 => '9', - 8315 => '−', - 8319 => 'n', - 8320 => '0', - 8321 => '1', - 8322 => '2', - 8323 => '3', - 8324 => '4', - 8325 => '5', - 8326 => '6', - 8327 => '7', - 8328 => '8', - 8329 => '9', - 8331 => '−', - 8336 => 'a', - 8337 => 'e', - 8338 => 'o', - 8339 => 'x', - 8340 => 'ə', - 8341 => 'h', - 8342 => 'k', - 8343 => 'l', - 8344 => 'm', - 8345 => 'n', - 8346 => 'p', - 8347 => 's', - 8348 => 't', - 8360 => 'rs', - 8450 => 'c', - 8451 => '°c', - 8455 => 'ɛ', - 8457 => '°f', - 8458 => 'g', - 8459 => 'h', - 8460 => 'h', - 8461 => 'h', - 8462 => 'h', - 8463 => 'ħ', - 8464 => 'i', - 8465 => 'i', - 8466 => 'l', - 8467 => 'l', - 8469 => 'n', - 8470 => 'no', - 8473 => 'p', - 8474 => 'q', - 8475 => 'r', - 8476 => 'r', - 8477 => 'r', - 8480 => 'sm', - 8481 => 'tel', - 8482 => 'tm', - 8484 => 'z', - 8486 => 'ω', - 8488 => 'z', - 8490 => 'k', - 8491 => 'å', - 8492 => 'b', - 8493 => 'c', - 8495 => 'e', - 8496 => 'e', - 8497 => 'f', - 8499 => 'm', - 8500 => 'o', - 8501 => 'א', - 8502 => 'ב', - 8503 => 'ג', - 8504 => 'ד', - 8505 => 'i', - 8507 => 'fax', - 8508 => 'π', - 8509 => 'γ', - 8510 => 'γ', - 8511 => 'π', - 8512 => '∑', - 8517 => 'd', - 8518 => 'd', - 8519 => 'e', - 8520 => 'i', - 8521 => 'j', - 8528 => '1⁄7', - 8529 => '1⁄9', - 8530 => '1⁄10', - 8531 => '1⁄3', - 8532 => '2⁄3', - 8533 => '1⁄5', - 8534 => '2⁄5', - 8535 => '3⁄5', - 8536 => '4⁄5', - 8537 => '1⁄6', - 8538 => '5⁄6', - 8539 => '1⁄8', - 8540 => '3⁄8', - 8541 => '5⁄8', - 8542 => '7⁄8', - 8543 => '1⁄', - 8544 => 'i', - 8545 => 'ii', - 8546 => 'iii', - 8547 => 'iv', - 8548 => 'v', - 8549 => 'vi', - 8550 => 'vii', - 8551 => 'viii', - 8552 => 'ix', - 8553 => 'x', - 8554 => 'xi', - 8555 => 'xii', - 8556 => 'l', - 8557 => 'c', - 8558 => 'd', - 8559 => 'm', - 8560 => 'i', - 8561 => 'ii', - 8562 => 'iii', - 8563 => 'iv', - 8564 => 'v', - 8565 => 'vi', - 8566 => 'vii', - 8567 => 'viii', - 8568 => 'ix', - 8569 => 'x', - 8570 => 'xi', - 8571 => 'xii', - 8572 => 'l', - 8573 => 'c', - 8574 => 'd', - 8575 => 'm', - 8585 => '0⁄3', - 8748 => '∫∫', - 8749 => '∫∫∫', - 8751 => '∮∮', - 8752 => '∮∮∮', - 9001 => '〈', - 9002 => '〉', - 9312 => '1', - 9313 => '2', - 9314 => '3', - 9315 => '4', - 9316 => '5', - 9317 => '6', - 9318 => '7', - 9319 => '8', - 9320 => '9', - 9321 => '10', - 9322 => '11', - 9323 => '12', - 9324 => '13', - 9325 => '14', - 9326 => '15', - 9327 => '16', - 9328 => '17', - 9329 => '18', - 9330 => '19', - 9331 => '20', - 9398 => 'a', - 9399 => 'b', - 9400 => 'c', - 9401 => 'd', - 9402 => 'e', - 9403 => 'f', - 9404 => 'g', - 9405 => 'h', - 9406 => 'i', - 9407 => 'j', - 9408 => 'k', - 9409 => 'l', - 9410 => 'm', - 9411 => 'n', - 9412 => 'o', - 9413 => 'p', - 9414 => 'q', - 9415 => 'r', - 9416 => 's', - 9417 => 't', - 9418 => 'u', - 9419 => 'v', - 9420 => 'w', - 9421 => 'x', - 9422 => 'y', - 9423 => 'z', - 9424 => 'a', - 9425 => 'b', - 9426 => 'c', - 9427 => 'd', - 9428 => 'e', - 9429 => 'f', - 9430 => 'g', - 9431 => 'h', - 9432 => 'i', - 9433 => 'j', - 9434 => 'k', - 9435 => 'l', - 9436 => 'm', - 9437 => 'n', - 9438 => 'o', - 9439 => 'p', - 9440 => 'q', - 9441 => 'r', - 9442 => 's', - 9443 => 't', - 9444 => 'u', - 9445 => 'v', - 9446 => 'w', - 9447 => 'x', - 9448 => 'y', - 9449 => 'z', - 9450 => '0', - 10764 => '∫∫∫∫', - 10972 => '⫝̸', - 11264 => 'ⰰ', - 11265 => 'ⰱ', - 11266 => 'ⰲ', - 11267 => 'ⰳ', - 11268 => 'ⰴ', - 11269 => 'ⰵ', - 11270 => 'ⰶ', - 11271 => 'ⰷ', - 11272 => 'ⰸ', - 11273 => 'ⰹ', - 11274 => 'ⰺ', - 11275 => 'ⰻ', - 11276 => 'ⰼ', - 11277 => 'ⰽ', - 11278 => 'ⰾ', - 11279 => 'ⰿ', - 11280 => 'ⱀ', - 11281 => 'ⱁ', - 11282 => 'ⱂ', - 11283 => 'ⱃ', - 11284 => 'ⱄ', - 11285 => 'ⱅ', - 11286 => 'ⱆ', - 11287 => 'ⱇ', - 11288 => 'ⱈ', - 11289 => 'ⱉ', - 11290 => 'ⱊ', - 11291 => 'ⱋ', - 11292 => 'ⱌ', - 11293 => 'ⱍ', - 11294 => 'ⱎ', - 11295 => 'ⱏ', - 11296 => 'ⱐ', - 11297 => 'ⱑ', - 11298 => 'ⱒ', - 11299 => 'ⱓ', - 11300 => 'ⱔ', - 11301 => 'ⱕ', - 11302 => 'ⱖ', - 11303 => 'ⱗ', - 11304 => 'ⱘ', - 11305 => 'ⱙ', - 11306 => 'ⱚ', - 11307 => 'ⱛ', - 11308 => 'ⱜ', - 11309 => 'ⱝ', - 11310 => 'ⱞ', - 11360 => 'ⱡ', - 11362 => 'ɫ', - 11363 => 'ᵽ', - 11364 => 'ɽ', - 11367 => 'ⱨ', - 11369 => 'ⱪ', - 11371 => 'ⱬ', - 11373 => 'ɑ', - 11374 => 'ɱ', - 11375 => 'ɐ', - 11376 => 'ɒ', - 11378 => 'ⱳ', - 11381 => 'ⱶ', - 11388 => 'j', - 11389 => 'v', - 11390 => 'ȿ', - 11391 => 'ɀ', - 11392 => 'ⲁ', - 11394 => 'ⲃ', - 11396 => 'ⲅ', - 11398 => 'ⲇ', - 11400 => 'ⲉ', - 11402 => 'ⲋ', - 11404 => 'ⲍ', - 11406 => 'ⲏ', - 11408 => 'ⲑ', - 11410 => 'ⲓ', - 11412 => 'ⲕ', - 11414 => 'ⲗ', - 11416 => 'ⲙ', - 11418 => 'ⲛ', - 11420 => 'ⲝ', - 11422 => 'ⲟ', - 11424 => 'ⲡ', - 11426 => 'ⲣ', - 11428 => 'ⲥ', - 11430 => 'ⲧ', - 11432 => 'ⲩ', - 11434 => 'ⲫ', - 11436 => 'ⲭ', - 11438 => 'ⲯ', - 11440 => 'ⲱ', - 11442 => 'ⲳ', - 11444 => 'ⲵ', - 11446 => 'ⲷ', - 11448 => 'ⲹ', - 11450 => 'ⲻ', - 11452 => 'ⲽ', - 11454 => 'ⲿ', - 11456 => 'ⳁ', - 11458 => 'ⳃ', - 11460 => 'ⳅ', - 11462 => 'ⳇ', - 11464 => 'ⳉ', - 11466 => 'ⳋ', - 11468 => 'ⳍ', - 11470 => 'ⳏ', - 11472 => 'ⳑ', - 11474 => 'ⳓ', - 11476 => 'ⳕ', - 11478 => 'ⳗ', - 11480 => 'ⳙ', - 11482 => 'ⳛ', - 11484 => 'ⳝ', - 11486 => 'ⳟ', - 11488 => 'ⳡ', - 11490 => 'ⳣ', - 11499 => 'ⳬ', - 11501 => 'ⳮ', - 11506 => 'ⳳ', - 11631 => 'ⵡ', - 11935 => '母', - 12019 => '龟', - 12032 => '一', - 12033 => '丨', - 12034 => '丶', - 12035 => '丿', - 12036 => '乙', - 12037 => '亅', - 12038 => '二', - 12039 => '亠', - 12040 => '人', - 12041 => '儿', - 12042 => '入', - 12043 => '八', - 12044 => '冂', - 12045 => '冖', - 12046 => '冫', - 12047 => '几', - 12048 => '凵', - 12049 => '刀', - 12050 => '力', - 12051 => '勹', - 12052 => '匕', - 12053 => '匚', - 12054 => '匸', - 12055 => '十', - 12056 => '卜', - 12057 => '卩', - 12058 => '厂', - 12059 => '厶', - 12060 => '又', - 12061 => '口', - 12062 => '囗', - 12063 => '土', - 12064 => '士', - 12065 => '夂', - 12066 => '夊', - 12067 => '夕', - 12068 => '大', - 12069 => '女', - 12070 => '子', - 12071 => '宀', - 12072 => '寸', - 12073 => '小', - 12074 => '尢', - 12075 => '尸', - 12076 => '屮', - 12077 => '山', - 12078 => '巛', - 12079 => '工', - 12080 => '己', - 12081 => '巾', - 12082 => '干', - 12083 => '幺', - 12084 => '广', - 12085 => '廴', - 12086 => '廾', - 12087 => '弋', - 12088 => '弓', - 12089 => '彐', - 12090 => '彡', - 12091 => '彳', - 12092 => '心', - 12093 => '戈', - 12094 => '戶', - 12095 => '手', - 12096 => '支', - 12097 => '攴', - 12098 => '文', - 12099 => '斗', - 12100 => '斤', - 12101 => '方', - 12102 => '无', - 12103 => '日', - 12104 => '曰', - 12105 => '月', - 12106 => '木', - 12107 => '欠', - 12108 => '止', - 12109 => '歹', - 12110 => '殳', - 12111 => '毋', - 12112 => '比', - 12113 => '毛', - 12114 => '氏', - 12115 => '气', - 12116 => '水', - 12117 => '火', - 12118 => '爪', - 12119 => '父', - 12120 => '爻', - 12121 => '爿', - 12122 => '片', - 12123 => '牙', - 12124 => '牛', - 12125 => '犬', - 12126 => '玄', - 12127 => '玉', - 12128 => '瓜', - 12129 => '瓦', - 12130 => '甘', - 12131 => '生', - 12132 => '用', - 12133 => '田', - 12134 => '疋', - 12135 => '疒', - 12136 => '癶', - 12137 => '白', - 12138 => '皮', - 12139 => '皿', - 12140 => '目', - 12141 => '矛', - 12142 => '矢', - 12143 => '石', - 12144 => '示', - 12145 => '禸', - 12146 => '禾', - 12147 => '穴', - 12148 => '立', - 12149 => '竹', - 12150 => '米', - 12151 => '糸', - 12152 => '缶', - 12153 => '网', - 12154 => '羊', - 12155 => '羽', - 12156 => '老', - 12157 => '而', - 12158 => '耒', - 12159 => '耳', - 12160 => '聿', - 12161 => '肉', - 12162 => '臣', - 12163 => '自', - 12164 => '至', - 12165 => '臼', - 12166 => '舌', - 12167 => '舛', - 12168 => '舟', - 12169 => '艮', - 12170 => '色', - 12171 => '艸', - 12172 => '虍', - 12173 => '虫', - 12174 => '血', - 12175 => '行', - 12176 => '衣', - 12177 => '襾', - 12178 => '見', - 12179 => '角', - 12180 => '言', - 12181 => '谷', - 12182 => '豆', - 12183 => '豕', - 12184 => '豸', - 12185 => '貝', - 12186 => '赤', - 12187 => '走', - 12188 => '足', - 12189 => '身', - 12190 => '車', - 12191 => '辛', - 12192 => '辰', - 12193 => '辵', - 12194 => '邑', - 12195 => '酉', - 12196 => '釆', - 12197 => '里', - 12198 => '金', - 12199 => '長', - 12200 => '門', - 12201 => '阜', - 12202 => '隶', - 12203 => '隹', - 12204 => '雨', - 12205 => '靑', - 12206 => '非', - 12207 => '面', - 12208 => '革', - 12209 => '韋', - 12210 => '韭', - 12211 => '音', - 12212 => '頁', - 12213 => '風', - 12214 => '飛', - 12215 => '食', - 12216 => '首', - 12217 => '香', - 12218 => '馬', - 12219 => '骨', - 12220 => '高', - 12221 => '髟', - 12222 => '鬥', - 12223 => '鬯', - 12224 => '鬲', - 12225 => '鬼', - 12226 => '魚', - 12227 => '鳥', - 12228 => '鹵', - 12229 => '鹿', - 12230 => '麥', - 12231 => '麻', - 12232 => '黃', - 12233 => '黍', - 12234 => '黑', - 12235 => '黹', - 12236 => '黽', - 12237 => '鼎', - 12238 => '鼓', - 12239 => '鼠', - 12240 => '鼻', - 12241 => '齊', - 12242 => '齒', - 12243 => '龍', - 12244 => '龜', - 12245 => '龠', - 12290 => '.', - 12342 => '〒', - 12344 => '十', - 12345 => '卄', - 12346 => '卅', - 12447 => 'より', - 12543 => 'コト', - 12593 => 'ᄀ', - 12594 => 'ᄁ', - 12595 => 'ᆪ', - 12596 => 'ᄂ', - 12597 => 'ᆬ', - 12598 => 'ᆭ', - 12599 => 'ᄃ', - 12600 => 'ᄄ', - 12601 => 'ᄅ', - 12602 => 'ᆰ', - 12603 => 'ᆱ', - 12604 => 'ᆲ', - 12605 => 'ᆳ', - 12606 => 'ᆴ', - 12607 => 'ᆵ', - 12608 => 'ᄚ', - 12609 => 'ᄆ', - 12610 => 'ᄇ', - 12611 => 'ᄈ', - 12612 => 'ᄡ', - 12613 => 'ᄉ', - 12614 => 'ᄊ', - 12615 => 'ᄋ', - 12616 => 'ᄌ', - 12617 => 'ᄍ', - 12618 => 'ᄎ', - 12619 => 'ᄏ', - 12620 => 'ᄐ', - 12621 => 'ᄑ', - 12622 => 'ᄒ', - 12623 => 'ᅡ', - 12624 => 'ᅢ', - 12625 => 'ᅣ', - 12626 => 'ᅤ', - 12627 => 'ᅥ', - 12628 => 'ᅦ', - 12629 => 'ᅧ', - 12630 => 'ᅨ', - 12631 => 'ᅩ', - 12632 => 'ᅪ', - 12633 => 'ᅫ', - 12634 => 'ᅬ', - 12635 => 'ᅭ', - 12636 => 'ᅮ', - 12637 => 'ᅯ', - 12638 => 'ᅰ', - 12639 => 'ᅱ', - 12640 => 'ᅲ', - 12641 => 'ᅳ', - 12642 => 'ᅴ', - 12643 => 'ᅵ', - 12645 => 'ᄔ', - 12646 => 'ᄕ', - 12647 => 'ᇇ', - 12648 => 'ᇈ', - 12649 => 'ᇌ', - 12650 => 'ᇎ', - 12651 => 'ᇓ', - 12652 => 'ᇗ', - 12653 => 'ᇙ', - 12654 => 'ᄜ', - 12655 => 'ᇝ', - 12656 => 'ᇟ', - 12657 => 'ᄝ', - 12658 => 'ᄞ', - 12659 => 'ᄠ', - 12660 => 'ᄢ', - 12661 => 'ᄣ', - 12662 => 'ᄧ', - 12663 => 'ᄩ', - 12664 => 'ᄫ', - 12665 => 'ᄬ', - 12666 => 'ᄭ', - 12667 => 'ᄮ', - 12668 => 'ᄯ', - 12669 => 'ᄲ', - 12670 => 'ᄶ', - 12671 => 'ᅀ', - 12672 => 'ᅇ', - 12673 => 'ᅌ', - 12674 => 'ᇱ', - 12675 => 'ᇲ', - 12676 => 'ᅗ', - 12677 => 'ᅘ', - 12678 => 'ᅙ', - 12679 => 'ᆄ', - 12680 => 'ᆅ', - 12681 => 'ᆈ', - 12682 => 'ᆑ', - 12683 => 'ᆒ', - 12684 => 'ᆔ', - 12685 => 'ᆞ', - 12686 => 'ᆡ', - 12690 => '一', - 12691 => '二', - 12692 => '三', - 12693 => '四', - 12694 => '上', - 12695 => '中', - 12696 => '下', - 12697 => '甲', - 12698 => '乙', - 12699 => '丙', - 12700 => '丁', - 12701 => '天', - 12702 => '地', - 12703 => '人', - 12868 => '問', - 12869 => '幼', - 12870 => '文', - 12871 => '箏', - 12880 => 'pte', - 12881 => '21', - 12882 => '22', - 12883 => '23', - 12884 => '24', - 12885 => '25', - 12886 => '26', - 12887 => '27', - 12888 => '28', - 12889 => '29', - 12890 => '30', - 12891 => '31', - 12892 => '32', - 12893 => '33', - 12894 => '34', - 12895 => '35', - 12896 => 'ᄀ', - 12897 => 'ᄂ', - 12898 => 'ᄃ', - 12899 => 'ᄅ', - 12900 => 'ᄆ', - 12901 => 'ᄇ', - 12902 => 'ᄉ', - 12903 => 'ᄋ', - 12904 => 'ᄌ', - 12905 => 'ᄎ', - 12906 => 'ᄏ', - 12907 => 'ᄐ', - 12908 => 'ᄑ', - 12909 => 'ᄒ', - 12910 => '가', - 12911 => '나', - 12912 => '다', - 12913 => '라', - 12914 => '마', - 12915 => '바', - 12916 => '사', - 12917 => '아', - 12918 => '자', - 12919 => '차', - 12920 => '카', - 12921 => '타', - 12922 => '파', - 12923 => '하', - 12924 => '참고', - 12925 => '주의', - 12926 => '우', - 12928 => '一', - 12929 => '二', - 12930 => '三', - 12931 => '四', - 12932 => '五', - 12933 => '六', - 12934 => '七', - 12935 => '八', - 12936 => '九', - 12937 => '十', - 12938 => '月', - 12939 => '火', - 12940 => '水', - 12941 => '木', - 12942 => '金', - 12943 => '土', - 12944 => '日', - 12945 => '株', - 12946 => '有', - 12947 => '社', - 12948 => '名', - 12949 => '特', - 12950 => '財', - 12951 => '祝', - 12952 => '労', - 12953 => '秘', - 12954 => '男', - 12955 => '女', - 12956 => '適', - 12957 => '優', - 12958 => '印', - 12959 => '注', - 12960 => '項', - 12961 => '休', - 12962 => '写', - 12963 => '正', - 12964 => '上', - 12965 => '中', - 12966 => '下', - 12967 => '左', - 12968 => '右', - 12969 => '医', - 12970 => '宗', - 12971 => '学', - 12972 => '監', - 12973 => '企', - 12974 => '資', - 12975 => '協', - 12976 => '夜', - 12977 => '36', - 12978 => '37', - 12979 => '38', - 12980 => '39', - 12981 => '40', - 12982 => '41', - 12983 => '42', - 12984 => '43', - 12985 => '44', - 12986 => '45', - 12987 => '46', - 12988 => '47', - 12989 => '48', - 12990 => '49', - 12991 => '50', - 12992 => '1月', - 12993 => '2月', - 12994 => '3月', - 12995 => '4月', - 12996 => '5月', - 12997 => '6月', - 12998 => '7月', - 12999 => '8月', - 13000 => '9月', - 13001 => '10月', - 13002 => '11月', - 13003 => '12月', - 13004 => 'hg', - 13005 => 'erg', - 13006 => 'ev', - 13007 => 'ltd', - 13008 => 'ア', - 13009 => 'イ', - 13010 => 'ウ', - 13011 => 'エ', - 13012 => 'オ', - 13013 => 'カ', - 13014 => 'キ', - 13015 => 'ク', - 13016 => 'ケ', - 13017 => 'コ', - 13018 => 'サ', - 13019 => 'シ', - 13020 => 'ス', - 13021 => 'セ', - 13022 => 'ソ', - 13023 => 'タ', - 13024 => 'チ', - 13025 => 'ツ', - 13026 => 'テ', - 13027 => 'ト', - 13028 => 'ナ', - 13029 => 'ニ', - 13030 => 'ヌ', - 13031 => 'ネ', - 13032 => 'ノ', - 13033 => 'ハ', - 13034 => 'ヒ', - 13035 => 'フ', - 13036 => 'ヘ', - 13037 => 'ホ', - 13038 => 'マ', - 13039 => 'ミ', - 13040 => 'ム', - 13041 => 'メ', - 13042 => 'モ', - 13043 => 'ヤ', - 13044 => 'ユ', - 13045 => 'ヨ', - 13046 => 'ラ', - 13047 => 'リ', - 13048 => 'ル', - 13049 => 'レ', - 13050 => 'ロ', - 13051 => 'ワ', - 13052 => 'ヰ', - 13053 => 'ヱ', - 13054 => 'ヲ', - 13055 => '令和', - 13056 => 'アパート', - 13057 => 'アルファ', - 13058 => 'アンペア', - 13059 => 'アール', - 13060 => 'イニング', - 13061 => 'インチ', - 13062 => 'ウォン', - 13063 => 'エスクード', - 13064 => 'エーカー', - 13065 => 'オンス', - 13066 => 'オーム', - 13067 => 'カイリ', - 13068 => 'カラット', - 13069 => 'カロリー', - 13070 => 'ガロン', - 13071 => 'ガンマ', - 13072 => 'ギガ', - 13073 => 'ギニー', - 13074 => 'キュリー', - 13075 => 'ギルダー', - 13076 => 'キロ', - 13077 => 'キログラム', - 13078 => 'キロメートル', - 13079 => 'キロワット', - 13080 => 'グラム', - 13081 => 'グラムトン', - 13082 => 'クルゼイロ', - 13083 => 'クローネ', - 13084 => 'ケース', - 13085 => 'コルナ', - 13086 => 'コーポ', - 13087 => 'サイクル', - 13088 => 'サンチーム', - 13089 => 'シリング', - 13090 => 'センチ', - 13091 => 'セント', - 13092 => 'ダース', - 13093 => 'デシ', - 13094 => 'ドル', - 13095 => 'トン', - 13096 => 'ナノ', - 13097 => 'ノット', - 13098 => 'ハイツ', - 13099 => 'パーセント', - 13100 => 'パーツ', - 13101 => 'バーレル', - 13102 => 'ピアストル', - 13103 => 'ピクル', - 13104 => 'ピコ', - 13105 => 'ビル', - 13106 => 'ファラッド', - 13107 => 'フィート', - 13108 => 'ブッシェル', - 13109 => 'フラン', - 13110 => 'ヘクタール', - 13111 => 'ペソ', - 13112 => 'ペニヒ', - 13113 => 'ヘルツ', - 13114 => 'ペンス', - 13115 => 'ページ', - 13116 => 'ベータ', - 13117 => 'ポイント', - 13118 => 'ボルト', - 13119 => 'ホン', - 13120 => 'ポンド', - 13121 => 'ホール', - 13122 => 'ホーン', - 13123 => 'マイクロ', - 13124 => 'マイル', - 13125 => 'マッハ', - 13126 => 'マルク', - 13127 => 'マンション', - 13128 => 'ミクロン', - 13129 => 'ミリ', - 13130 => 'ミリバール', - 13131 => 'メガ', - 13132 => 'メガトン', - 13133 => 'メートル', - 13134 => 'ヤード', - 13135 => 'ヤール', - 13136 => 'ユアン', - 13137 => 'リットル', - 13138 => 'リラ', - 13139 => 'ルピー', - 13140 => 'ルーブル', - 13141 => 'レム', - 13142 => 'レントゲン', - 13143 => 'ワット', - 13144 => '0点', - 13145 => '1点', - 13146 => '2点', - 13147 => '3点', - 13148 => '4点', - 13149 => '5点', - 13150 => '6点', - 13151 => '7点', - 13152 => '8点', - 13153 => '9点', - 13154 => '10点', - 13155 => '11点', - 13156 => '12点', - 13157 => '13点', - 13158 => '14点', - 13159 => '15点', - 13160 => '16点', - 13161 => '17点', - 13162 => '18点', - 13163 => '19点', - 13164 => '20点', - 13165 => '21点', - 13166 => '22点', - 13167 => '23点', - 13168 => '24点', - 13169 => 'hpa', - 13170 => 'da', - 13171 => 'au', - 13172 => 'bar', - 13173 => 'ov', - 13174 => 'pc', - 13175 => 'dm', - 13176 => 'dm2', - 13177 => 'dm3', - 13178 => 'iu', - 13179 => '平成', - 13180 => '昭和', - 13181 => '大正', - 13182 => '明治', - 13183 => '株式会社', - 13184 => 'pa', - 13185 => 'na', - 13186 => 'μa', - 13187 => 'ma', - 13188 => 'ka', - 13189 => 'kb', - 13190 => 'mb', - 13191 => 'gb', - 13192 => 'cal', - 13193 => 'kcal', - 13194 => 'pf', - 13195 => 'nf', - 13196 => 'μf', - 13197 => 'μg', - 13198 => 'mg', - 13199 => 'kg', - 13200 => 'hz', - 13201 => 'khz', - 13202 => 'mhz', - 13203 => 'ghz', - 13204 => 'thz', - 13205 => 'μl', - 13206 => 'ml', - 13207 => 'dl', - 13208 => 'kl', - 13209 => 'fm', - 13210 => 'nm', - 13211 => 'μm', - 13212 => 'mm', - 13213 => 'cm', - 13214 => 'km', - 13215 => 'mm2', - 13216 => 'cm2', - 13217 => 'm2', - 13218 => 'km2', - 13219 => 'mm3', - 13220 => 'cm3', - 13221 => 'm3', - 13222 => 'km3', - 13223 => 'm∕s', - 13224 => 'm∕s2', - 13225 => 'pa', - 13226 => 'kpa', - 13227 => 'mpa', - 13228 => 'gpa', - 13229 => 'rad', - 13230 => 'rad∕s', - 13231 => 'rad∕s2', - 13232 => 'ps', - 13233 => 'ns', - 13234 => 'μs', - 13235 => 'ms', - 13236 => 'pv', - 13237 => 'nv', - 13238 => 'μv', - 13239 => 'mv', - 13240 => 'kv', - 13241 => 'mv', - 13242 => 'pw', - 13243 => 'nw', - 13244 => 'μw', - 13245 => 'mw', - 13246 => 'kw', - 13247 => 'mw', - 13248 => 'kω', - 13249 => 'mω', - 13251 => 'bq', - 13252 => 'cc', - 13253 => 'cd', - 13254 => 'c∕kg', - 13256 => 'db', - 13257 => 'gy', - 13258 => 'ha', - 13259 => 'hp', - 13260 => 'in', - 13261 => 'kk', - 13262 => 'km', - 13263 => 'kt', - 13264 => 'lm', - 13265 => 'ln', - 13266 => 'log', - 13267 => 'lx', - 13268 => 'mb', - 13269 => 'mil', - 13270 => 'mol', - 13271 => 'ph', - 13273 => 'ppm', - 13274 => 'pr', - 13275 => 'sr', - 13276 => 'sv', - 13277 => 'wb', - 13278 => 'v∕m', - 13279 => 'a∕m', - 13280 => '1日', - 13281 => '2日', - 13282 => '3日', - 13283 => '4日', - 13284 => '5日', - 13285 => '6日', - 13286 => '7日', - 13287 => '8日', - 13288 => '9日', - 13289 => '10日', - 13290 => '11日', - 13291 => '12日', - 13292 => '13日', - 13293 => '14日', - 13294 => '15日', - 13295 => '16日', - 13296 => '17日', - 13297 => '18日', - 13298 => '19日', - 13299 => '20日', - 13300 => '21日', - 13301 => '22日', - 13302 => '23日', - 13303 => '24日', - 13304 => '25日', - 13305 => '26日', - 13306 => '27日', - 13307 => '28日', - 13308 => '29日', - 13309 => '30日', - 13310 => '31日', - 13311 => 'gal', - 42560 => 'ꙁ', - 42562 => 'ꙃ', - 42564 => 'ꙅ', - 42566 => 'ꙇ', - 42568 => 'ꙉ', - 42570 => 'ꙋ', - 42572 => 'ꙍ', - 42574 => 'ꙏ', - 42576 => 'ꙑ', - 42578 => 'ꙓ', - 42580 => 'ꙕ', - 42582 => 'ꙗ', - 42584 => 'ꙙ', - 42586 => 'ꙛ', - 42588 => 'ꙝ', - 42590 => 'ꙟ', - 42592 => 'ꙡ', - 42594 => 'ꙣ', - 42596 => 'ꙥ', - 42598 => 'ꙧ', - 42600 => 'ꙩ', - 42602 => 'ꙫ', - 42604 => 'ꙭ', - 42624 => 'ꚁ', - 42626 => 'ꚃ', - 42628 => 'ꚅ', - 42630 => 'ꚇ', - 42632 => 'ꚉ', - 42634 => 'ꚋ', - 42636 => 'ꚍ', - 42638 => 'ꚏ', - 42640 => 'ꚑ', - 42642 => 'ꚓ', - 42644 => 'ꚕ', - 42646 => 'ꚗ', - 42648 => 'ꚙ', - 42650 => 'ꚛ', - 42652 => 'ъ', - 42653 => 'ь', - 42786 => 'ꜣ', - 42788 => 'ꜥ', - 42790 => 'ꜧ', - 42792 => 'ꜩ', - 42794 => 'ꜫ', - 42796 => 'ꜭ', - 42798 => 'ꜯ', - 42802 => 'ꜳ', - 42804 => 'ꜵ', - 42806 => 'ꜷ', - 42808 => 'ꜹ', - 42810 => 'ꜻ', - 42812 => 'ꜽ', - 42814 => 'ꜿ', - 42816 => 'ꝁ', - 42818 => 'ꝃ', - 42820 => 'ꝅ', - 42822 => 'ꝇ', - 42824 => 'ꝉ', - 42826 => 'ꝋ', - 42828 => 'ꝍ', - 42830 => 'ꝏ', - 42832 => 'ꝑ', - 42834 => 'ꝓ', - 42836 => 'ꝕ', - 42838 => 'ꝗ', - 42840 => 'ꝙ', - 42842 => 'ꝛ', - 42844 => 'ꝝ', - 42846 => 'ꝟ', - 42848 => 'ꝡ', - 42850 => 'ꝣ', - 42852 => 'ꝥ', - 42854 => 'ꝧ', - 42856 => 'ꝩ', - 42858 => 'ꝫ', - 42860 => 'ꝭ', - 42862 => 'ꝯ', - 42864 => 'ꝯ', - 42873 => 'ꝺ', - 42875 => 'ꝼ', - 42877 => 'ᵹ', - 42878 => 'ꝿ', - 42880 => 'ꞁ', - 42882 => 'ꞃ', - 42884 => 'ꞅ', - 42886 => 'ꞇ', - 42891 => 'ꞌ', - 42893 => 'ɥ', - 42896 => 'ꞑ', - 42898 => 'ꞓ', - 42902 => 'ꞗ', - 42904 => 'ꞙ', - 42906 => 'ꞛ', - 42908 => 'ꞝ', - 42910 => 'ꞟ', - 42912 => 'ꞡ', - 42914 => 'ꞣ', - 42916 => 'ꞥ', - 42918 => 'ꞧ', - 42920 => 'ꞩ', - 42922 => 'ɦ', - 42923 => 'ɜ', - 42924 => 'ɡ', - 42925 => 'ɬ', - 42926 => 'ɪ', - 42928 => 'ʞ', - 42929 => 'ʇ', - 42930 => 'ʝ', - 42931 => 'ꭓ', - 42932 => 'ꞵ', - 42934 => 'ꞷ', - 42936 => 'ꞹ', - 42938 => 'ꞻ', - 42940 => 'ꞽ', - 42942 => 'ꞿ', - 42946 => 'ꟃ', - 42948 => 'ꞔ', - 42949 => 'ʂ', - 42950 => 'ᶎ', - 42951 => 'ꟈ', - 42953 => 'ꟊ', - 42997 => 'ꟶ', - 43000 => 'ħ', - 43001 => 'œ', - 43868 => 'ꜧ', - 43869 => 'ꬷ', - 43870 => 'ɫ', - 43871 => 'ꭒ', - 43881 => 'ʍ', - 43888 => 'Ꭰ', - 43889 => 'Ꭱ', - 43890 => 'Ꭲ', - 43891 => 'Ꭳ', - 43892 => 'Ꭴ', - 43893 => 'Ꭵ', - 43894 => 'Ꭶ', - 43895 => 'Ꭷ', - 43896 => 'Ꭸ', - 43897 => 'Ꭹ', - 43898 => 'Ꭺ', - 43899 => 'Ꭻ', - 43900 => 'Ꭼ', - 43901 => 'Ꭽ', - 43902 => 'Ꭾ', - 43903 => 'Ꭿ', - 43904 => 'Ꮀ', - 43905 => 'Ꮁ', - 43906 => 'Ꮂ', - 43907 => 'Ꮃ', - 43908 => 'Ꮄ', - 43909 => 'Ꮅ', - 43910 => 'Ꮆ', - 43911 => 'Ꮇ', - 43912 => 'Ꮈ', - 43913 => 'Ꮉ', - 43914 => 'Ꮊ', - 43915 => 'Ꮋ', - 43916 => 'Ꮌ', - 43917 => 'Ꮍ', - 43918 => 'Ꮎ', - 43919 => 'Ꮏ', - 43920 => 'Ꮐ', - 43921 => 'Ꮑ', - 43922 => 'Ꮒ', - 43923 => 'Ꮓ', - 43924 => 'Ꮔ', - 43925 => 'Ꮕ', - 43926 => 'Ꮖ', - 43927 => 'Ꮗ', - 43928 => 'Ꮘ', - 43929 => 'Ꮙ', - 43930 => 'Ꮚ', - 43931 => 'Ꮛ', - 43932 => 'Ꮜ', - 43933 => 'Ꮝ', - 43934 => 'Ꮞ', - 43935 => 'Ꮟ', - 43936 => 'Ꮠ', - 43937 => 'Ꮡ', - 43938 => 'Ꮢ', - 43939 => 'Ꮣ', - 43940 => 'Ꮤ', - 43941 => 'Ꮥ', - 43942 => 'Ꮦ', - 43943 => 'Ꮧ', - 43944 => 'Ꮨ', - 43945 => 'Ꮩ', - 43946 => 'Ꮪ', - 43947 => 'Ꮫ', - 43948 => 'Ꮬ', - 43949 => 'Ꮭ', - 43950 => 'Ꮮ', - 43951 => 'Ꮯ', - 43952 => 'Ꮰ', - 43953 => 'Ꮱ', - 43954 => 'Ꮲ', - 43955 => 'Ꮳ', - 43956 => 'Ꮴ', - 43957 => 'Ꮵ', - 43958 => 'Ꮶ', - 43959 => 'Ꮷ', - 43960 => 'Ꮸ', - 43961 => 'Ꮹ', - 43962 => 'Ꮺ', - 43963 => 'Ꮻ', - 43964 => 'Ꮼ', - 43965 => 'Ꮽ', - 43966 => 'Ꮾ', - 43967 => 'Ꮿ', - 63744 => '豈', - 63745 => '更', - 63746 => '車', - 63747 => '賈', - 63748 => '滑', - 63749 => '串', - 63750 => '句', - 63751 => '龜', - 63752 => '龜', - 63753 => '契', - 63754 => '金', - 63755 => '喇', - 63756 => '奈', - 63757 => '懶', - 63758 => '癩', - 63759 => '羅', - 63760 => '蘿', - 63761 => '螺', - 63762 => '裸', - 63763 => '邏', - 63764 => '樂', - 63765 => '洛', - 63766 => '烙', - 63767 => '珞', - 63768 => '落', - 63769 => '酪', - 63770 => '駱', - 63771 => '亂', - 63772 => '卵', - 63773 => '欄', - 63774 => '爛', - 63775 => '蘭', - 63776 => '鸞', - 63777 => '嵐', - 63778 => '濫', - 63779 => '藍', - 63780 => '襤', - 63781 => '拉', - 63782 => '臘', - 63783 => '蠟', - 63784 => '廊', - 63785 => '朗', - 63786 => '浪', - 63787 => '狼', - 63788 => '郎', - 63789 => '來', - 63790 => '冷', - 63791 => '勞', - 63792 => '擄', - 63793 => '櫓', - 63794 => '爐', - 63795 => '盧', - 63796 => '老', - 63797 => '蘆', - 63798 => '虜', - 63799 => '路', - 63800 => '露', - 63801 => '魯', - 63802 => '鷺', - 63803 => '碌', - 63804 => '祿', - 63805 => '綠', - 63806 => '菉', - 63807 => '錄', - 63808 => '鹿', - 63809 => '論', - 63810 => '壟', - 63811 => '弄', - 63812 => '籠', - 63813 => '聾', - 63814 => '牢', - 63815 => '磊', - 63816 => '賂', - 63817 => '雷', - 63818 => '壘', - 63819 => '屢', - 63820 => '樓', - 63821 => '淚', - 63822 => '漏', - 63823 => '累', - 63824 => '縷', - 63825 => '陋', - 63826 => '勒', - 63827 => '肋', - 63828 => '凜', - 63829 => '凌', - 63830 => '稜', - 63831 => '綾', - 63832 => '菱', - 63833 => '陵', - 63834 => '讀', - 63835 => '拏', - 63836 => '樂', - 63837 => '諾', - 63838 => '丹', - 63839 => '寧', - 63840 => '怒', - 63841 => '率', - 63842 => '異', - 63843 => '北', - 63844 => '磻', - 63845 => '便', - 63846 => '復', - 63847 => '不', - 63848 => '泌', - 63849 => '數', - 63850 => '索', - 63851 => '參', - 63852 => '塞', - 63853 => '省', - 63854 => '葉', - 63855 => '說', - 63856 => '殺', - 63857 => '辰', - 63858 => '沈', - 63859 => '拾', - 63860 => '若', - 63861 => '掠', - 63862 => '略', - 63863 => '亮', - 63864 => '兩', - 63865 => '凉', - 63866 => '梁', - 63867 => '糧', - 63868 => '良', - 63869 => '諒', - 63870 => '量', - 63871 => '勵', - 63872 => '呂', - 63873 => '女', - 63874 => '廬', - 63875 => '旅', - 63876 => '濾', - 63877 => '礪', - 63878 => '閭', - 63879 => '驪', - 63880 => '麗', - 63881 => '黎', - 63882 => '力', - 63883 => '曆', - 63884 => '歷', - 63885 => '轢', - 63886 => '年', - 63887 => '憐', - 63888 => '戀', - 63889 => '撚', - 63890 => '漣', - 63891 => '煉', - 63892 => '璉', - 63893 => '秊', - 63894 => '練', - 63895 => '聯', - 63896 => '輦', - 63897 => '蓮', - 63898 => '連', - 63899 => '鍊', - 63900 => '列', - 63901 => '劣', - 63902 => '咽', - 63903 => '烈', - 63904 => '裂', - 63905 => '說', - 63906 => '廉', - 63907 => '念', - 63908 => '捻', - 63909 => '殮', - 63910 => '簾', - 63911 => '獵', - 63912 => '令', - 63913 => '囹', - 63914 => '寧', - 63915 => '嶺', - 63916 => '怜', - 63917 => '玲', - 63918 => '瑩', - 63919 => '羚', - 63920 => '聆', - 63921 => '鈴', - 63922 => '零', - 63923 => '靈', - 63924 => '領', - 63925 => '例', - 63926 => '禮', - 63927 => '醴', - 63928 => '隸', - 63929 => '惡', - 63930 => '了', - 63931 => '僚', - 63932 => '寮', - 63933 => '尿', - 63934 => '料', - 63935 => '樂', - 63936 => '燎', - 63937 => '療', - 63938 => '蓼', - 63939 => '遼', - 63940 => '龍', - 63941 => '暈', - 63942 => '阮', - 63943 => '劉', - 63944 => '杻', - 63945 => '柳', - 63946 => '流', - 63947 => '溜', - 63948 => '琉', - 63949 => '留', - 63950 => '硫', - 63951 => '紐', - 63952 => '類', - 63953 => '六', - 63954 => '戮', - 63955 => '陸', - 63956 => '倫', - 63957 => '崙', - 63958 => '淪', - 63959 => '輪', - 63960 => '律', - 63961 => '慄', - 63962 => '栗', - 63963 => '率', - 63964 => '隆', - 63965 => '利', - 63966 => '吏', - 63967 => '履', - 63968 => '易', - 63969 => '李', - 63970 => '梨', - 63971 => '泥', - 63972 => '理', - 63973 => '痢', - 63974 => '罹', - 63975 => '裏', - 63976 => '裡', - 63977 => '里', - 63978 => '離', - 63979 => '匿', - 63980 => '溺', - 63981 => '吝', - 63982 => '燐', - 63983 => '璘', - 63984 => '藺', - 63985 => '隣', - 63986 => '鱗', - 63987 => '麟', - 63988 => '林', - 63989 => '淋', - 63990 => '臨', - 63991 => '立', - 63992 => '笠', - 63993 => '粒', - 63994 => '狀', - 63995 => '炙', - 63996 => '識', - 63997 => '什', - 63998 => '茶', - 63999 => '刺', - 64000 => '切', - 64001 => '度', - 64002 => '拓', - 64003 => '糖', - 64004 => '宅', - 64005 => '洞', - 64006 => '暴', - 64007 => '輻', - 64008 => '行', - 64009 => '降', - 64010 => '見', - 64011 => '廓', - 64012 => '兀', - 64013 => '嗀', - 64016 => '塚', - 64018 => '晴', - 64021 => '凞', - 64022 => '猪', - 64023 => '益', - 64024 => '礼', - 64025 => '神', - 64026 => '祥', - 64027 => '福', - 64028 => '靖', - 64029 => '精', - 64030 => '羽', - 64032 => '蘒', - 64034 => '諸', - 64037 => '逸', - 64038 => '都', - 64042 => '飯', - 64043 => '飼', - 64044 => '館', - 64045 => '鶴', - 64046 => '郞', - 64047 => '隷', - 64048 => '侮', - 64049 => '僧', - 64050 => '免', - 64051 => '勉', - 64052 => '勤', - 64053 => '卑', - 64054 => '喝', - 64055 => '嘆', - 64056 => '器', - 64057 => '塀', - 64058 => '墨', - 64059 => '層', - 64060 => '屮', - 64061 => '悔', - 64062 => '慨', - 64063 => '憎', - 64064 => '懲', - 64065 => '敏', - 64066 => '既', - 64067 => '暑', - 64068 => '梅', - 64069 => '海', - 64070 => '渚', - 64071 => '漢', - 64072 => '煮', - 64073 => '爫', - 64074 => '琢', - 64075 => '碑', - 64076 => '社', - 64077 => '祉', - 64078 => '祈', - 64079 => '祐', - 64080 => '祖', - 64081 => '祝', - 64082 => '禍', - 64083 => '禎', - 64084 => '穀', - 64085 => '突', - 64086 => '節', - 64087 => '練', - 64088 => '縉', - 64089 => '繁', - 64090 => '署', - 64091 => '者', - 64092 => '臭', - 64093 => '艹', - 64094 => '艹', - 64095 => '著', - 64096 => '褐', - 64097 => '視', - 64098 => '謁', - 64099 => '謹', - 64100 => '賓', - 64101 => '贈', - 64102 => '辶', - 64103 => '逸', - 64104 => '難', - 64105 => '響', - 64106 => '頻', - 64107 => '恵', - 64108 => '𤋮', - 64109 => '舘', - 64112 => '並', - 64113 => '况', - 64114 => '全', - 64115 => '侀', - 64116 => '充', - 64117 => '冀', - 64118 => '勇', - 64119 => '勺', - 64120 => '喝', - 64121 => '啕', - 64122 => '喙', - 64123 => '嗢', - 64124 => '塚', - 64125 => '墳', - 64126 => '奄', - 64127 => '奔', - 64128 => '婢', - 64129 => '嬨', - 64130 => '廒', - 64131 => '廙', - 64132 => '彩', - 64133 => '徭', - 64134 => '惘', - 64135 => '慎', - 64136 => '愈', - 64137 => '憎', - 64138 => '慠', - 64139 => '懲', - 64140 => '戴', - 64141 => '揄', - 64142 => '搜', - 64143 => '摒', - 64144 => '敖', - 64145 => '晴', - 64146 => '朗', - 64147 => '望', - 64148 => '杖', - 64149 => '歹', - 64150 => '殺', - 64151 => '流', - 64152 => '滛', - 64153 => '滋', - 64154 => '漢', - 64155 => '瀞', - 64156 => '煮', - 64157 => '瞧', - 64158 => '爵', - 64159 => '犯', - 64160 => '猪', - 64161 => '瑱', - 64162 => '甆', - 64163 => '画', - 64164 => '瘝', - 64165 => '瘟', - 64166 => '益', - 64167 => '盛', - 64168 => '直', - 64169 => '睊', - 64170 => '着', - 64171 => '磌', - 64172 => '窱', - 64173 => '節', - 64174 => '类', - 64175 => '絛', - 64176 => '練', - 64177 => '缾', - 64178 => '者', - 64179 => '荒', - 64180 => '華', - 64181 => '蝹', - 64182 => '襁', - 64183 => '覆', - 64184 => '視', - 64185 => '調', - 64186 => '諸', - 64187 => '請', - 64188 => '謁', - 64189 => '諾', - 64190 => '諭', - 64191 => '謹', - 64192 => '變', - 64193 => '贈', - 64194 => '輸', - 64195 => '遲', - 64196 => '醙', - 64197 => '鉶', - 64198 => '陼', - 64199 => '難', - 64200 => '靖', - 64201 => '韛', - 64202 => '響', - 64203 => '頋', - 64204 => '頻', - 64205 => '鬒', - 64206 => '龜', - 64207 => '𢡊', - 64208 => '𢡄', - 64209 => '𣏕', - 64210 => '㮝', - 64211 => '䀘', - 64212 => '䀹', - 64213 => '𥉉', - 64214 => '𥳐', - 64215 => '𧻓', - 64216 => '齃', - 64217 => '龎', - 64256 => 'ff', - 64257 => 'fi', - 64258 => 'fl', - 64259 => 'ffi', - 64260 => 'ffl', - 64261 => 'st', - 64262 => 'st', - 64275 => 'մն', - 64276 => 'մե', - 64277 => 'մի', - 64278 => 'վն', - 64279 => 'մխ', - 64285 => 'יִ', - 64287 => 'ײַ', - 64288 => 'ע', - 64289 => 'א', - 64290 => 'ד', - 64291 => 'ה', - 64292 => 'כ', - 64293 => 'ל', - 64294 => 'ם', - 64295 => 'ר', - 64296 => 'ת', - 64298 => 'שׁ', - 64299 => 'שׂ', - 64300 => 'שּׁ', - 64301 => 'שּׂ', - 64302 => 'אַ', - 64303 => 'אָ', - 64304 => 'אּ', - 64305 => 'בּ', - 64306 => 'גּ', - 64307 => 'דּ', - 64308 => 'הּ', - 64309 => 'וּ', - 64310 => 'זּ', - 64312 => 'טּ', - 64313 => 'יּ', - 64314 => 'ךּ', - 64315 => 'כּ', - 64316 => 'לּ', - 64318 => 'מּ', - 64320 => 'נּ', - 64321 => 'סּ', - 64323 => 'ףּ', - 64324 => 'פּ', - 64326 => 'צּ', - 64327 => 'קּ', - 64328 => 'רּ', - 64329 => 'שּ', - 64330 => 'תּ', - 64331 => 'וֹ', - 64332 => 'בֿ', - 64333 => 'כֿ', - 64334 => 'פֿ', - 64335 => 'אל', - 64336 => 'ٱ', - 64337 => 'ٱ', - 64338 => 'ٻ', - 64339 => 'ٻ', - 64340 => 'ٻ', - 64341 => 'ٻ', - 64342 => 'پ', - 64343 => 'پ', - 64344 => 'پ', - 64345 => 'پ', - 64346 => 'ڀ', - 64347 => 'ڀ', - 64348 => 'ڀ', - 64349 => 'ڀ', - 64350 => 'ٺ', - 64351 => 'ٺ', - 64352 => 'ٺ', - 64353 => 'ٺ', - 64354 => 'ٿ', - 64355 => 'ٿ', - 64356 => 'ٿ', - 64357 => 'ٿ', - 64358 => 'ٹ', - 64359 => 'ٹ', - 64360 => 'ٹ', - 64361 => 'ٹ', - 64362 => 'ڤ', - 64363 => 'ڤ', - 64364 => 'ڤ', - 64365 => 'ڤ', - 64366 => 'ڦ', - 64367 => 'ڦ', - 64368 => 'ڦ', - 64369 => 'ڦ', - 64370 => 'ڄ', - 64371 => 'ڄ', - 64372 => 'ڄ', - 64373 => 'ڄ', - 64374 => 'ڃ', - 64375 => 'ڃ', - 64376 => 'ڃ', - 64377 => 'ڃ', - 64378 => 'چ', - 64379 => 'چ', - 64380 => 'چ', - 64381 => 'چ', - 64382 => 'ڇ', - 64383 => 'ڇ', - 64384 => 'ڇ', - 64385 => 'ڇ', - 64386 => 'ڍ', - 64387 => 'ڍ', - 64388 => 'ڌ', - 64389 => 'ڌ', - 64390 => 'ڎ', - 64391 => 'ڎ', - 64392 => 'ڈ', - 64393 => 'ڈ', - 64394 => 'ژ', - 64395 => 'ژ', - 64396 => 'ڑ', - 64397 => 'ڑ', - 64398 => 'ک', - 64399 => 'ک', - 64400 => 'ک', - 64401 => 'ک', - 64402 => 'گ', - 64403 => 'گ', - 64404 => 'گ', - 64405 => 'گ', - 64406 => 'ڳ', - 64407 => 'ڳ', - 64408 => 'ڳ', - 64409 => 'ڳ', - 64410 => 'ڱ', - 64411 => 'ڱ', - 64412 => 'ڱ', - 64413 => 'ڱ', - 64414 => 'ں', - 64415 => 'ں', - 64416 => 'ڻ', - 64417 => 'ڻ', - 64418 => 'ڻ', - 64419 => 'ڻ', - 64420 => 'ۀ', - 64421 => 'ۀ', - 64422 => 'ہ', - 64423 => 'ہ', - 64424 => 'ہ', - 64425 => 'ہ', - 64426 => 'ھ', - 64427 => 'ھ', - 64428 => 'ھ', - 64429 => 'ھ', - 64430 => 'ے', - 64431 => 'ے', - 64432 => 'ۓ', - 64433 => 'ۓ', - 64467 => 'ڭ', - 64468 => 'ڭ', - 64469 => 'ڭ', - 64470 => 'ڭ', - 64471 => 'ۇ', - 64472 => 'ۇ', - 64473 => 'ۆ', - 64474 => 'ۆ', - 64475 => 'ۈ', - 64476 => 'ۈ', - 64477 => 'ۇٴ', - 64478 => 'ۋ', - 64479 => 'ۋ', - 64480 => 'ۅ', - 64481 => 'ۅ', - 64482 => 'ۉ', - 64483 => 'ۉ', - 64484 => 'ې', - 64485 => 'ې', - 64486 => 'ې', - 64487 => 'ې', - 64488 => 'ى', - 64489 => 'ى', - 64490 => 'ئا', - 64491 => 'ئا', - 64492 => 'ئە', - 64493 => 'ئە', - 64494 => 'ئو', - 64495 => 'ئو', - 64496 => 'ئۇ', - 64497 => 'ئۇ', - 64498 => 'ئۆ', - 64499 => 'ئۆ', - 64500 => 'ئۈ', - 64501 => 'ئۈ', - 64502 => 'ئې', - 64503 => 'ئې', - 64504 => 'ئې', - 64505 => 'ئى', - 64506 => 'ئى', - 64507 => 'ئى', - 64508 => 'ی', - 64509 => 'ی', - 64510 => 'ی', - 64511 => 'ی', - 64512 => 'ئج', - 64513 => 'ئح', - 64514 => 'ئم', - 64515 => 'ئى', - 64516 => 'ئي', - 64517 => 'بج', - 64518 => 'بح', - 64519 => 'بخ', - 64520 => 'بم', - 64521 => 'بى', - 64522 => 'بي', - 64523 => 'تج', - 64524 => 'تح', - 64525 => 'تخ', - 64526 => 'تم', - 64527 => 'تى', - 64528 => 'تي', - 64529 => 'ثج', - 64530 => 'ثم', - 64531 => 'ثى', - 64532 => 'ثي', - 64533 => 'جح', - 64534 => 'جم', - 64535 => 'حج', - 64536 => 'حم', - 64537 => 'خج', - 64538 => 'خح', - 64539 => 'خم', - 64540 => 'سج', - 64541 => 'سح', - 64542 => 'سخ', - 64543 => 'سم', - 64544 => 'صح', - 64545 => 'صم', - 64546 => 'ضج', - 64547 => 'ضح', - 64548 => 'ضخ', - 64549 => 'ضم', - 64550 => 'طح', - 64551 => 'طم', - 64552 => 'ظم', - 64553 => 'عج', - 64554 => 'عم', - 64555 => 'غج', - 64556 => 'غم', - 64557 => 'فج', - 64558 => 'فح', - 64559 => 'فخ', - 64560 => 'فم', - 64561 => 'فى', - 64562 => 'في', - 64563 => 'قح', - 64564 => 'قم', - 64565 => 'قى', - 64566 => 'قي', - 64567 => 'كا', - 64568 => 'كج', - 64569 => 'كح', - 64570 => 'كخ', - 64571 => 'كل', - 64572 => 'كم', - 64573 => 'كى', - 64574 => 'كي', - 64575 => 'لج', - 64576 => 'لح', - 64577 => 'لخ', - 64578 => 'لم', - 64579 => 'لى', - 64580 => 'لي', - 64581 => 'مج', - 64582 => 'مح', - 64583 => 'مخ', - 64584 => 'مم', - 64585 => 'مى', - 64586 => 'مي', - 64587 => 'نج', - 64588 => 'نح', - 64589 => 'نخ', - 64590 => 'نم', - 64591 => 'نى', - 64592 => 'ني', - 64593 => 'هج', - 64594 => 'هم', - 64595 => 'هى', - 64596 => 'هي', - 64597 => 'يج', - 64598 => 'يح', - 64599 => 'يخ', - 64600 => 'يم', - 64601 => 'يى', - 64602 => 'يي', - 64603 => 'ذٰ', - 64604 => 'رٰ', - 64605 => 'ىٰ', - 64612 => 'ئر', - 64613 => 'ئز', - 64614 => 'ئم', - 64615 => 'ئن', - 64616 => 'ئى', - 64617 => 'ئي', - 64618 => 'بر', - 64619 => 'بز', - 64620 => 'بم', - 64621 => 'بن', - 64622 => 'بى', - 64623 => 'بي', - 64624 => 'تر', - 64625 => 'تز', - 64626 => 'تم', - 64627 => 'تن', - 64628 => 'تى', - 64629 => 'تي', - 64630 => 'ثر', - 64631 => 'ثز', - 64632 => 'ثم', - 64633 => 'ثن', - 64634 => 'ثى', - 64635 => 'ثي', - 64636 => 'فى', - 64637 => 'في', - 64638 => 'قى', - 64639 => 'قي', - 64640 => 'كا', - 64641 => 'كل', - 64642 => 'كم', - 64643 => 'كى', - 64644 => 'كي', - 64645 => 'لم', - 64646 => 'لى', - 64647 => 'لي', - 64648 => 'ما', - 64649 => 'مم', - 64650 => 'نر', - 64651 => 'نز', - 64652 => 'نم', - 64653 => 'نن', - 64654 => 'نى', - 64655 => 'ني', - 64656 => 'ىٰ', - 64657 => 'ير', - 64658 => 'يز', - 64659 => 'يم', - 64660 => 'ين', - 64661 => 'يى', - 64662 => 'يي', - 64663 => 'ئج', - 64664 => 'ئح', - 64665 => 'ئخ', - 64666 => 'ئم', - 64667 => 'ئه', - 64668 => 'بج', - 64669 => 'بح', - 64670 => 'بخ', - 64671 => 'بم', - 64672 => 'به', - 64673 => 'تج', - 64674 => 'تح', - 64675 => 'تخ', - 64676 => 'تم', - 64677 => 'ته', - 64678 => 'ثم', - 64679 => 'جح', - 64680 => 'جم', - 64681 => 'حج', - 64682 => 'حم', - 64683 => 'خج', - 64684 => 'خم', - 64685 => 'سج', - 64686 => 'سح', - 64687 => 'سخ', - 64688 => 'سم', - 64689 => 'صح', - 64690 => 'صخ', - 64691 => 'صم', - 64692 => 'ضج', - 64693 => 'ضح', - 64694 => 'ضخ', - 64695 => 'ضم', - 64696 => 'طح', - 64697 => 'ظم', - 64698 => 'عج', - 64699 => 'عم', - 64700 => 'غج', - 64701 => 'غم', - 64702 => 'فج', - 64703 => 'فح', - 64704 => 'فخ', - 64705 => 'فم', - 64706 => 'قح', - 64707 => 'قم', - 64708 => 'كج', - 64709 => 'كح', - 64710 => 'كخ', - 64711 => 'كل', - 64712 => 'كم', - 64713 => 'لج', - 64714 => 'لح', - 64715 => 'لخ', - 64716 => 'لم', - 64717 => 'له', - 64718 => 'مج', - 64719 => 'مح', - 64720 => 'مخ', - 64721 => 'مم', - 64722 => 'نج', - 64723 => 'نح', - 64724 => 'نخ', - 64725 => 'نم', - 64726 => 'نه', - 64727 => 'هج', - 64728 => 'هم', - 64729 => 'هٰ', - 64730 => 'يج', - 64731 => 'يح', - 64732 => 'يخ', - 64733 => 'يم', - 64734 => 'يه', - 64735 => 'ئم', - 64736 => 'ئه', - 64737 => 'بم', - 64738 => 'به', - 64739 => 'تم', - 64740 => 'ته', - 64741 => 'ثم', - 64742 => 'ثه', - 64743 => 'سم', - 64744 => 'سه', - 64745 => 'شم', - 64746 => 'شه', - 64747 => 'كل', - 64748 => 'كم', - 64749 => 'لم', - 64750 => 'نم', - 64751 => 'نه', - 64752 => 'يم', - 64753 => 'يه', - 64754 => 'ـَّ', - 64755 => 'ـُّ', - 64756 => 'ـِّ', - 64757 => 'طى', - 64758 => 'طي', - 64759 => 'عى', - 64760 => 'عي', - 64761 => 'غى', - 64762 => 'غي', - 64763 => 'سى', - 64764 => 'سي', - 64765 => 'شى', - 64766 => 'شي', - 64767 => 'حى', - 64768 => 'حي', - 64769 => 'جى', - 64770 => 'جي', - 64771 => 'خى', - 64772 => 'خي', - 64773 => 'صى', - 64774 => 'صي', - 64775 => 'ضى', - 64776 => 'ضي', - 64777 => 'شج', - 64778 => 'شح', - 64779 => 'شخ', - 64780 => 'شم', - 64781 => 'شر', - 64782 => 'سر', - 64783 => 'صر', - 64784 => 'ضر', - 64785 => 'طى', - 64786 => 'طي', - 64787 => 'عى', - 64788 => 'عي', - 64789 => 'غى', - 64790 => 'غي', - 64791 => 'سى', - 64792 => 'سي', - 64793 => 'شى', - 64794 => 'شي', - 64795 => 'حى', - 64796 => 'حي', - 64797 => 'جى', - 64798 => 'جي', - 64799 => 'خى', - 64800 => 'خي', - 64801 => 'صى', - 64802 => 'صي', - 64803 => 'ضى', - 64804 => 'ضي', - 64805 => 'شج', - 64806 => 'شح', - 64807 => 'شخ', - 64808 => 'شم', - 64809 => 'شر', - 64810 => 'سر', - 64811 => 'صر', - 64812 => 'ضر', - 64813 => 'شج', - 64814 => 'شح', - 64815 => 'شخ', - 64816 => 'شم', - 64817 => 'سه', - 64818 => 'شه', - 64819 => 'طم', - 64820 => 'سج', - 64821 => 'سح', - 64822 => 'سخ', - 64823 => 'شج', - 64824 => 'شح', - 64825 => 'شخ', - 64826 => 'طم', - 64827 => 'ظم', - 64828 => 'اً', - 64829 => 'اً', - 64848 => 'تجم', - 64849 => 'تحج', - 64850 => 'تحج', - 64851 => 'تحم', - 64852 => 'تخم', - 64853 => 'تمج', - 64854 => 'تمح', - 64855 => 'تمخ', - 64856 => 'جمح', - 64857 => 'جمح', - 64858 => 'حمي', - 64859 => 'حمى', - 64860 => 'سحج', - 64861 => 'سجح', - 64862 => 'سجى', - 64863 => 'سمح', - 64864 => 'سمح', - 64865 => 'سمج', - 64866 => 'سمم', - 64867 => 'سمم', - 64868 => 'صحح', - 64869 => 'صحح', - 64870 => 'صمم', - 64871 => 'شحم', - 64872 => 'شحم', - 64873 => 'شجي', - 64874 => 'شمخ', - 64875 => 'شمخ', - 64876 => 'شمم', - 64877 => 'شمم', - 64878 => 'ضحى', - 64879 => 'ضخم', - 64880 => 'ضخم', - 64881 => 'طمح', - 64882 => 'طمح', - 64883 => 'طمم', - 64884 => 'طمي', - 64885 => 'عجم', - 64886 => 'عمم', - 64887 => 'عمم', - 64888 => 'عمى', - 64889 => 'غمم', - 64890 => 'غمي', - 64891 => 'غمى', - 64892 => 'فخم', - 64893 => 'فخم', - 64894 => 'قمح', - 64895 => 'قمم', - 64896 => 'لحم', - 64897 => 'لحي', - 64898 => 'لحى', - 64899 => 'لجج', - 64900 => 'لجج', - 64901 => 'لخم', - 64902 => 'لخم', - 64903 => 'لمح', - 64904 => 'لمح', - 64905 => 'محج', - 64906 => 'محم', - 64907 => 'محي', - 64908 => 'مجح', - 64909 => 'مجم', - 64910 => 'مخج', - 64911 => 'مخم', - 64914 => 'مجخ', - 64915 => 'همج', - 64916 => 'همم', - 64917 => 'نحم', - 64918 => 'نحى', - 64919 => 'نجم', - 64920 => 'نجم', - 64921 => 'نجى', - 64922 => 'نمي', - 64923 => 'نمى', - 64924 => 'يمم', - 64925 => 'يمم', - 64926 => 'بخي', - 64927 => 'تجي', - 64928 => 'تجى', - 64929 => 'تخي', - 64930 => 'تخى', - 64931 => 'تمي', - 64932 => 'تمى', - 64933 => 'جمي', - 64934 => 'جحى', - 64935 => 'جمى', - 64936 => 'سخى', - 64937 => 'صحي', - 64938 => 'شحي', - 64939 => 'ضحي', - 64940 => 'لجي', - 64941 => 'لمي', - 64942 => 'يحي', - 64943 => 'يجي', - 64944 => 'يمي', - 64945 => 'ممي', - 64946 => 'قمي', - 64947 => 'نحي', - 64948 => 'قمح', - 64949 => 'لحم', - 64950 => 'عمي', - 64951 => 'كمي', - 64952 => 'نجح', - 64953 => 'مخي', - 64954 => 'لجم', - 64955 => 'كمم', - 64956 => 'لجم', - 64957 => 'نجح', - 64958 => 'جحي', - 64959 => 'حجي', - 64960 => 'مجي', - 64961 => 'فمي', - 64962 => 'بحي', - 64963 => 'كمم', - 64964 => 'عجم', - 64965 => 'صمم', - 64966 => 'سخي', - 64967 => 'نجي', - 65008 => 'صلے', - 65009 => 'قلے', - 65010 => 'الله', - 65011 => 'اكبر', - 65012 => 'محمد', - 65013 => 'صلعم', - 65014 => 'رسول', - 65015 => 'عليه', - 65016 => 'وسلم', - 65017 => 'صلى', - 65020 => 'ریال', - 65041 => '、', - 65047 => '〖', - 65048 => '〗', - 65073 => '—', - 65074 => '–', - 65081 => '〔', - 65082 => '〕', - 65083 => '【', - 65084 => '】', - 65085 => '《', - 65086 => '》', - 65087 => '〈', - 65088 => '〉', - 65089 => '「', - 65090 => '」', - 65091 => '『', - 65092 => '』', - 65105 => '、', - 65112 => '—', - 65117 => '〔', - 65118 => '〕', - 65123 => '-', - 65137 => 'ـً', - 65143 => 'ـَ', - 65145 => 'ـُ', - 65147 => 'ـِ', - 65149 => 'ـّ', - 65151 => 'ـْ', - 65152 => 'ء', - 65153 => 'آ', - 65154 => 'آ', - 65155 => 'أ', - 65156 => 'أ', - 65157 => 'ؤ', - 65158 => 'ؤ', - 65159 => 'إ', - 65160 => 'إ', - 65161 => 'ئ', - 65162 => 'ئ', - 65163 => 'ئ', - 65164 => 'ئ', - 65165 => 'ا', - 65166 => 'ا', - 65167 => 'ب', - 65168 => 'ب', - 65169 => 'ب', - 65170 => 'ب', - 65171 => 'ة', - 65172 => 'ة', - 65173 => 'ت', - 65174 => 'ت', - 65175 => 'ت', - 65176 => 'ت', - 65177 => 'ث', - 65178 => 'ث', - 65179 => 'ث', - 65180 => 'ث', - 65181 => 'ج', - 65182 => 'ج', - 65183 => 'ج', - 65184 => 'ج', - 65185 => 'ح', - 65186 => 'ح', - 65187 => 'ح', - 65188 => 'ح', - 65189 => 'خ', - 65190 => 'خ', - 65191 => 'خ', - 65192 => 'خ', - 65193 => 'د', - 65194 => 'د', - 65195 => 'ذ', - 65196 => 'ذ', - 65197 => 'ر', - 65198 => 'ر', - 65199 => 'ز', - 65200 => 'ز', - 65201 => 'س', - 65202 => 'س', - 65203 => 'س', - 65204 => 'س', - 65205 => 'ش', - 65206 => 'ش', - 65207 => 'ش', - 65208 => 'ش', - 65209 => 'ص', - 65210 => 'ص', - 65211 => 'ص', - 65212 => 'ص', - 65213 => 'ض', - 65214 => 'ض', - 65215 => 'ض', - 65216 => 'ض', - 65217 => 'ط', - 65218 => 'ط', - 65219 => 'ط', - 65220 => 'ط', - 65221 => 'ظ', - 65222 => 'ظ', - 65223 => 'ظ', - 65224 => 'ظ', - 65225 => 'ع', - 65226 => 'ع', - 65227 => 'ع', - 65228 => 'ع', - 65229 => 'غ', - 65230 => 'غ', - 65231 => 'غ', - 65232 => 'غ', - 65233 => 'ف', - 65234 => 'ف', - 65235 => 'ف', - 65236 => 'ف', - 65237 => 'ق', - 65238 => 'ق', - 65239 => 'ق', - 65240 => 'ق', - 65241 => 'ك', - 65242 => 'ك', - 65243 => 'ك', - 65244 => 'ك', - 65245 => 'ل', - 65246 => 'ل', - 65247 => 'ل', - 65248 => 'ل', - 65249 => 'م', - 65250 => 'م', - 65251 => 'م', - 65252 => 'م', - 65253 => 'ن', - 65254 => 'ن', - 65255 => 'ن', - 65256 => 'ن', - 65257 => 'ه', - 65258 => 'ه', - 65259 => 'ه', - 65260 => 'ه', - 65261 => 'و', - 65262 => 'و', - 65263 => 'ى', - 65264 => 'ى', - 65265 => 'ي', - 65266 => 'ي', - 65267 => 'ي', - 65268 => 'ي', - 65269 => 'لآ', - 65270 => 'لآ', - 65271 => 'لأ', - 65272 => 'لأ', - 65273 => 'لإ', - 65274 => 'لإ', - 65275 => 'لا', - 65276 => 'لا', - 65293 => '-', - 65294 => '.', - 65296 => '0', - 65297 => '1', - 65298 => '2', - 65299 => '3', - 65300 => '4', - 65301 => '5', - 65302 => '6', - 65303 => '7', - 65304 => '8', - 65305 => '9', - 65313 => 'a', - 65314 => 'b', - 65315 => 'c', - 65316 => 'd', - 65317 => 'e', - 65318 => 'f', - 65319 => 'g', - 65320 => 'h', - 65321 => 'i', - 65322 => 'j', - 65323 => 'k', - 65324 => 'l', - 65325 => 'm', - 65326 => 'n', - 65327 => 'o', - 65328 => 'p', - 65329 => 'q', - 65330 => 'r', - 65331 => 's', - 65332 => 't', - 65333 => 'u', - 65334 => 'v', - 65335 => 'w', - 65336 => 'x', - 65337 => 'y', - 65338 => 'z', - 65345 => 'a', - 65346 => 'b', - 65347 => 'c', - 65348 => 'd', - 65349 => 'e', - 65350 => 'f', - 65351 => 'g', - 65352 => 'h', - 65353 => 'i', - 65354 => 'j', - 65355 => 'k', - 65356 => 'l', - 65357 => 'm', - 65358 => 'n', - 65359 => 'o', - 65360 => 'p', - 65361 => 'q', - 65362 => 'r', - 65363 => 's', - 65364 => 't', - 65365 => 'u', - 65366 => 'v', - 65367 => 'w', - 65368 => 'x', - 65369 => 'y', - 65370 => 'z', - 65375 => '⦅', - 65376 => '⦆', - 65377 => '.', - 65378 => '「', - 65379 => '」', - 65380 => '、', - 65381 => '・', - 65382 => 'ヲ', - 65383 => 'ァ', - 65384 => 'ィ', - 65385 => 'ゥ', - 65386 => 'ェ', - 65387 => 'ォ', - 65388 => 'ャ', - 65389 => 'ュ', - 65390 => 'ョ', - 65391 => 'ッ', - 65392 => 'ー', - 65393 => 'ア', - 65394 => 'イ', - 65395 => 'ウ', - 65396 => 'エ', - 65397 => 'オ', - 65398 => 'カ', - 65399 => 'キ', - 65400 => 'ク', - 65401 => 'ケ', - 65402 => 'コ', - 65403 => 'サ', - 65404 => 'シ', - 65405 => 'ス', - 65406 => 'セ', - 65407 => 'ソ', - 65408 => 'タ', - 65409 => 'チ', - 65410 => 'ツ', - 65411 => 'テ', - 65412 => 'ト', - 65413 => 'ナ', - 65414 => 'ニ', - 65415 => 'ヌ', - 65416 => 'ネ', - 65417 => 'ノ', - 65418 => 'ハ', - 65419 => 'ヒ', - 65420 => 'フ', - 65421 => 'ヘ', - 65422 => 'ホ', - 65423 => 'マ', - 65424 => 'ミ', - 65425 => 'ム', - 65426 => 'メ', - 65427 => 'モ', - 65428 => 'ヤ', - 65429 => 'ユ', - 65430 => 'ヨ', - 65431 => 'ラ', - 65432 => 'リ', - 65433 => 'ル', - 65434 => 'レ', - 65435 => 'ロ', - 65436 => 'ワ', - 65437 => 'ン', - 65438 => '゙', - 65439 => '゚', - 65441 => 'ᄀ', - 65442 => 'ᄁ', - 65443 => 'ᆪ', - 65444 => 'ᄂ', - 65445 => 'ᆬ', - 65446 => 'ᆭ', - 65447 => 'ᄃ', - 65448 => 'ᄄ', - 65449 => 'ᄅ', - 65450 => 'ᆰ', - 65451 => 'ᆱ', - 65452 => 'ᆲ', - 65453 => 'ᆳ', - 65454 => 'ᆴ', - 65455 => 'ᆵ', - 65456 => 'ᄚ', - 65457 => 'ᄆ', - 65458 => 'ᄇ', - 65459 => 'ᄈ', - 65460 => 'ᄡ', - 65461 => 'ᄉ', - 65462 => 'ᄊ', - 65463 => 'ᄋ', - 65464 => 'ᄌ', - 65465 => 'ᄍ', - 65466 => 'ᄎ', - 65467 => 'ᄏ', - 65468 => 'ᄐ', - 65469 => 'ᄑ', - 65470 => 'ᄒ', - 65474 => 'ᅡ', - 65475 => 'ᅢ', - 65476 => 'ᅣ', - 65477 => 'ᅤ', - 65478 => 'ᅥ', - 65479 => 'ᅦ', - 65482 => 'ᅧ', - 65483 => 'ᅨ', - 65484 => 'ᅩ', - 65485 => 'ᅪ', - 65486 => 'ᅫ', - 65487 => 'ᅬ', - 65490 => 'ᅭ', - 65491 => 'ᅮ', - 65492 => 'ᅯ', - 65493 => 'ᅰ', - 65494 => 'ᅱ', - 65495 => 'ᅲ', - 65498 => 'ᅳ', - 65499 => 'ᅴ', - 65500 => 'ᅵ', - 65504 => '¢', - 65505 => '£', - 65506 => '¬', - 65508 => '¦', - 65509 => '¥', - 65510 => '₩', - 65512 => '│', - 65513 => '←', - 65514 => '↑', - 65515 => '→', - 65516 => '↓', - 65517 => '■', - 65518 => '○', - 66560 => '𐐨', - 66561 => '𐐩', - 66562 => '𐐪', - 66563 => '𐐫', - 66564 => '𐐬', - 66565 => '𐐭', - 66566 => '𐐮', - 66567 => '𐐯', - 66568 => '𐐰', - 66569 => '𐐱', - 66570 => '𐐲', - 66571 => '𐐳', - 66572 => '𐐴', - 66573 => '𐐵', - 66574 => '𐐶', - 66575 => '𐐷', - 66576 => '𐐸', - 66577 => '𐐹', - 66578 => '𐐺', - 66579 => '𐐻', - 66580 => '𐐼', - 66581 => '𐐽', - 66582 => '𐐾', - 66583 => '𐐿', - 66584 => '𐑀', - 66585 => '𐑁', - 66586 => '𐑂', - 66587 => '𐑃', - 66588 => '𐑄', - 66589 => '𐑅', - 66590 => '𐑆', - 66591 => '𐑇', - 66592 => '𐑈', - 66593 => '𐑉', - 66594 => '𐑊', - 66595 => '𐑋', - 66596 => '𐑌', - 66597 => '𐑍', - 66598 => '𐑎', - 66599 => '𐑏', - 66736 => '𐓘', - 66737 => '𐓙', - 66738 => '𐓚', - 66739 => '𐓛', - 66740 => '𐓜', - 66741 => '𐓝', - 66742 => '𐓞', - 66743 => '𐓟', - 66744 => '𐓠', - 66745 => '𐓡', - 66746 => '𐓢', - 66747 => '𐓣', - 66748 => '𐓤', - 66749 => '𐓥', - 66750 => '𐓦', - 66751 => '𐓧', - 66752 => '𐓨', - 66753 => '𐓩', - 66754 => '𐓪', - 66755 => '𐓫', - 66756 => '𐓬', - 66757 => '𐓭', - 66758 => '𐓮', - 66759 => '𐓯', - 66760 => '𐓰', - 66761 => '𐓱', - 66762 => '𐓲', - 66763 => '𐓳', - 66764 => '𐓴', - 66765 => '𐓵', - 66766 => '𐓶', - 66767 => '𐓷', - 66768 => '𐓸', - 66769 => '𐓹', - 66770 => '𐓺', - 66771 => '𐓻', - 68736 => '𐳀', - 68737 => '𐳁', - 68738 => '𐳂', - 68739 => '𐳃', - 68740 => '𐳄', - 68741 => '𐳅', - 68742 => '𐳆', - 68743 => '𐳇', - 68744 => '𐳈', - 68745 => '𐳉', - 68746 => '𐳊', - 68747 => '𐳋', - 68748 => '𐳌', - 68749 => '𐳍', - 68750 => '𐳎', - 68751 => '𐳏', - 68752 => '𐳐', - 68753 => '𐳑', - 68754 => '𐳒', - 68755 => '𐳓', - 68756 => '𐳔', - 68757 => '𐳕', - 68758 => '𐳖', - 68759 => '𐳗', - 68760 => '𐳘', - 68761 => '𐳙', - 68762 => '𐳚', - 68763 => '𐳛', - 68764 => '𐳜', - 68765 => '𐳝', - 68766 => '𐳞', - 68767 => '𐳟', - 68768 => '𐳠', - 68769 => '𐳡', - 68770 => '𐳢', - 68771 => '𐳣', - 68772 => '𐳤', - 68773 => '𐳥', - 68774 => '𐳦', - 68775 => '𐳧', - 68776 => '𐳨', - 68777 => '𐳩', - 68778 => '𐳪', - 68779 => '𐳫', - 68780 => '𐳬', - 68781 => '𐳭', - 68782 => '𐳮', - 68783 => '𐳯', - 68784 => '𐳰', - 68785 => '𐳱', - 68786 => '𐳲', - 71840 => '𑣀', - 71841 => '𑣁', - 71842 => '𑣂', - 71843 => '𑣃', - 71844 => '𑣄', - 71845 => '𑣅', - 71846 => '𑣆', - 71847 => '𑣇', - 71848 => '𑣈', - 71849 => '𑣉', - 71850 => '𑣊', - 71851 => '𑣋', - 71852 => '𑣌', - 71853 => '𑣍', - 71854 => '𑣎', - 71855 => '𑣏', - 71856 => '𑣐', - 71857 => '𑣑', - 71858 => '𑣒', - 71859 => '𑣓', - 71860 => '𑣔', - 71861 => '𑣕', - 71862 => '𑣖', - 71863 => '𑣗', - 71864 => '𑣘', - 71865 => '𑣙', - 71866 => '𑣚', - 71867 => '𑣛', - 71868 => '𑣜', - 71869 => '𑣝', - 71870 => '𑣞', - 71871 => '𑣟', - 93760 => '𖹠', - 93761 => '𖹡', - 93762 => '𖹢', - 93763 => '𖹣', - 93764 => '𖹤', - 93765 => '𖹥', - 93766 => '𖹦', - 93767 => '𖹧', - 93768 => '𖹨', - 93769 => '𖹩', - 93770 => '𖹪', - 93771 => '𖹫', - 93772 => '𖹬', - 93773 => '𖹭', - 93774 => '𖹮', - 93775 => '𖹯', - 93776 => '𖹰', - 93777 => '𖹱', - 93778 => '𖹲', - 93779 => '𖹳', - 93780 => '𖹴', - 93781 => '𖹵', - 93782 => '𖹶', - 93783 => '𖹷', - 93784 => '𖹸', - 93785 => '𖹹', - 93786 => '𖹺', - 93787 => '𖹻', - 93788 => '𖹼', - 93789 => '𖹽', - 93790 => '𖹾', - 93791 => '𖹿', - 119134 => '𝅗𝅥', - 119135 => '𝅘𝅥', - 119136 => '𝅘𝅥𝅮', - 119137 => '𝅘𝅥𝅯', - 119138 => '𝅘𝅥𝅰', - 119139 => '𝅘𝅥𝅱', - 119140 => '𝅘𝅥𝅲', - 119227 => '𝆹𝅥', - 119228 => '𝆺𝅥', - 119229 => '𝆹𝅥𝅮', - 119230 => '𝆺𝅥𝅮', - 119231 => '𝆹𝅥𝅯', - 119232 => '𝆺𝅥𝅯', - 119808 => 'a', - 119809 => 'b', - 119810 => 'c', - 119811 => 'd', - 119812 => 'e', - 119813 => 'f', - 119814 => 'g', - 119815 => 'h', - 119816 => 'i', - 119817 => 'j', - 119818 => 'k', - 119819 => 'l', - 119820 => 'm', - 119821 => 'n', - 119822 => 'o', - 119823 => 'p', - 119824 => 'q', - 119825 => 'r', - 119826 => 's', - 119827 => 't', - 119828 => 'u', - 119829 => 'v', - 119830 => 'w', - 119831 => 'x', - 119832 => 'y', - 119833 => 'z', - 119834 => 'a', - 119835 => 'b', - 119836 => 'c', - 119837 => 'd', - 119838 => 'e', - 119839 => 'f', - 119840 => 'g', - 119841 => 'h', - 119842 => 'i', - 119843 => 'j', - 119844 => 'k', - 119845 => 'l', - 119846 => 'm', - 119847 => 'n', - 119848 => 'o', - 119849 => 'p', - 119850 => 'q', - 119851 => 'r', - 119852 => 's', - 119853 => 't', - 119854 => 'u', - 119855 => 'v', - 119856 => 'w', - 119857 => 'x', - 119858 => 'y', - 119859 => 'z', - 119860 => 'a', - 119861 => 'b', - 119862 => 'c', - 119863 => 'd', - 119864 => 'e', - 119865 => 'f', - 119866 => 'g', - 119867 => 'h', - 119868 => 'i', - 119869 => 'j', - 119870 => 'k', - 119871 => 'l', - 119872 => 'm', - 119873 => 'n', - 119874 => 'o', - 119875 => 'p', - 119876 => 'q', - 119877 => 'r', - 119878 => 's', - 119879 => 't', - 119880 => 'u', - 119881 => 'v', - 119882 => 'w', - 119883 => 'x', - 119884 => 'y', - 119885 => 'z', - 119886 => 'a', - 119887 => 'b', - 119888 => 'c', - 119889 => 'd', - 119890 => 'e', - 119891 => 'f', - 119892 => 'g', - 119894 => 'i', - 119895 => 'j', - 119896 => 'k', - 119897 => 'l', - 119898 => 'm', - 119899 => 'n', - 119900 => 'o', - 119901 => 'p', - 119902 => 'q', - 119903 => 'r', - 119904 => 's', - 119905 => 't', - 119906 => 'u', - 119907 => 'v', - 119908 => 'w', - 119909 => 'x', - 119910 => 'y', - 119911 => 'z', - 119912 => 'a', - 119913 => 'b', - 119914 => 'c', - 119915 => 'd', - 119916 => 'e', - 119917 => 'f', - 119918 => 'g', - 119919 => 'h', - 119920 => 'i', - 119921 => 'j', - 119922 => 'k', - 119923 => 'l', - 119924 => 'm', - 119925 => 'n', - 119926 => 'o', - 119927 => 'p', - 119928 => 'q', - 119929 => 'r', - 119930 => 's', - 119931 => 't', - 119932 => 'u', - 119933 => 'v', - 119934 => 'w', - 119935 => 'x', - 119936 => 'y', - 119937 => 'z', - 119938 => 'a', - 119939 => 'b', - 119940 => 'c', - 119941 => 'd', - 119942 => 'e', - 119943 => 'f', - 119944 => 'g', - 119945 => 'h', - 119946 => 'i', - 119947 => 'j', - 119948 => 'k', - 119949 => 'l', - 119950 => 'm', - 119951 => 'n', - 119952 => 'o', - 119953 => 'p', - 119954 => 'q', - 119955 => 'r', - 119956 => 's', - 119957 => 't', - 119958 => 'u', - 119959 => 'v', - 119960 => 'w', - 119961 => 'x', - 119962 => 'y', - 119963 => 'z', - 119964 => 'a', - 119966 => 'c', - 119967 => 'd', - 119970 => 'g', - 119973 => 'j', - 119974 => 'k', - 119977 => 'n', - 119978 => 'o', - 119979 => 'p', - 119980 => 'q', - 119982 => 's', - 119983 => 't', - 119984 => 'u', - 119985 => 'v', - 119986 => 'w', - 119987 => 'x', - 119988 => 'y', - 119989 => 'z', - 119990 => 'a', - 119991 => 'b', - 119992 => 'c', - 119993 => 'd', - 119995 => 'f', - 119997 => 'h', - 119998 => 'i', - 119999 => 'j', - 120000 => 'k', - 120001 => 'l', - 120002 => 'm', - 120003 => 'n', - 120005 => 'p', - 120006 => 'q', - 120007 => 'r', - 120008 => 's', - 120009 => 't', - 120010 => 'u', - 120011 => 'v', - 120012 => 'w', - 120013 => 'x', - 120014 => 'y', - 120015 => 'z', - 120016 => 'a', - 120017 => 'b', - 120018 => 'c', - 120019 => 'd', - 120020 => 'e', - 120021 => 'f', - 120022 => 'g', - 120023 => 'h', - 120024 => 'i', - 120025 => 'j', - 120026 => 'k', - 120027 => 'l', - 120028 => 'm', - 120029 => 'n', - 120030 => 'o', - 120031 => 'p', - 120032 => 'q', - 120033 => 'r', - 120034 => 's', - 120035 => 't', - 120036 => 'u', - 120037 => 'v', - 120038 => 'w', - 120039 => 'x', - 120040 => 'y', - 120041 => 'z', - 120042 => 'a', - 120043 => 'b', - 120044 => 'c', - 120045 => 'd', - 120046 => 'e', - 120047 => 'f', - 120048 => 'g', - 120049 => 'h', - 120050 => 'i', - 120051 => 'j', - 120052 => 'k', - 120053 => 'l', - 120054 => 'm', - 120055 => 'n', - 120056 => 'o', - 120057 => 'p', - 120058 => 'q', - 120059 => 'r', - 120060 => 's', - 120061 => 't', - 120062 => 'u', - 120063 => 'v', - 120064 => 'w', - 120065 => 'x', - 120066 => 'y', - 120067 => 'z', - 120068 => 'a', - 120069 => 'b', - 120071 => 'd', - 120072 => 'e', - 120073 => 'f', - 120074 => 'g', - 120077 => 'j', - 120078 => 'k', - 120079 => 'l', - 120080 => 'm', - 120081 => 'n', - 120082 => 'o', - 120083 => 'p', - 120084 => 'q', - 120086 => 's', - 120087 => 't', - 120088 => 'u', - 120089 => 'v', - 120090 => 'w', - 120091 => 'x', - 120092 => 'y', - 120094 => 'a', - 120095 => 'b', - 120096 => 'c', - 120097 => 'd', - 120098 => 'e', - 120099 => 'f', - 120100 => 'g', - 120101 => 'h', - 120102 => 'i', - 120103 => 'j', - 120104 => 'k', - 120105 => 'l', - 120106 => 'm', - 120107 => 'n', - 120108 => 'o', - 120109 => 'p', - 120110 => 'q', - 120111 => 'r', - 120112 => 's', - 120113 => 't', - 120114 => 'u', - 120115 => 'v', - 120116 => 'w', - 120117 => 'x', - 120118 => 'y', - 120119 => 'z', - 120120 => 'a', - 120121 => 'b', - 120123 => 'd', - 120124 => 'e', - 120125 => 'f', - 120126 => 'g', - 120128 => 'i', - 120129 => 'j', - 120130 => 'k', - 120131 => 'l', - 120132 => 'm', - 120134 => 'o', - 120138 => 's', - 120139 => 't', - 120140 => 'u', - 120141 => 'v', - 120142 => 'w', - 120143 => 'x', - 120144 => 'y', - 120146 => 'a', - 120147 => 'b', - 120148 => 'c', - 120149 => 'd', - 120150 => 'e', - 120151 => 'f', - 120152 => 'g', - 120153 => 'h', - 120154 => 'i', - 120155 => 'j', - 120156 => 'k', - 120157 => 'l', - 120158 => 'm', - 120159 => 'n', - 120160 => 'o', - 120161 => 'p', - 120162 => 'q', - 120163 => 'r', - 120164 => 's', - 120165 => 't', - 120166 => 'u', - 120167 => 'v', - 120168 => 'w', - 120169 => 'x', - 120170 => 'y', - 120171 => 'z', - 120172 => 'a', - 120173 => 'b', - 120174 => 'c', - 120175 => 'd', - 120176 => 'e', - 120177 => 'f', - 120178 => 'g', - 120179 => 'h', - 120180 => 'i', - 120181 => 'j', - 120182 => 'k', - 120183 => 'l', - 120184 => 'm', - 120185 => 'n', - 120186 => 'o', - 120187 => 'p', - 120188 => 'q', - 120189 => 'r', - 120190 => 's', - 120191 => 't', - 120192 => 'u', - 120193 => 'v', - 120194 => 'w', - 120195 => 'x', - 120196 => 'y', - 120197 => 'z', - 120198 => 'a', - 120199 => 'b', - 120200 => 'c', - 120201 => 'd', - 120202 => 'e', - 120203 => 'f', - 120204 => 'g', - 120205 => 'h', - 120206 => 'i', - 120207 => 'j', - 120208 => 'k', - 120209 => 'l', - 120210 => 'm', - 120211 => 'n', - 120212 => 'o', - 120213 => 'p', - 120214 => 'q', - 120215 => 'r', - 120216 => 's', - 120217 => 't', - 120218 => 'u', - 120219 => 'v', - 120220 => 'w', - 120221 => 'x', - 120222 => 'y', - 120223 => 'z', - 120224 => 'a', - 120225 => 'b', - 120226 => 'c', - 120227 => 'd', - 120228 => 'e', - 120229 => 'f', - 120230 => 'g', - 120231 => 'h', - 120232 => 'i', - 120233 => 'j', - 120234 => 'k', - 120235 => 'l', - 120236 => 'm', - 120237 => 'n', - 120238 => 'o', - 120239 => 'p', - 120240 => 'q', - 120241 => 'r', - 120242 => 's', - 120243 => 't', - 120244 => 'u', - 120245 => 'v', - 120246 => 'w', - 120247 => 'x', - 120248 => 'y', - 120249 => 'z', - 120250 => 'a', - 120251 => 'b', - 120252 => 'c', - 120253 => 'd', - 120254 => 'e', - 120255 => 'f', - 120256 => 'g', - 120257 => 'h', - 120258 => 'i', - 120259 => 'j', - 120260 => 'k', - 120261 => 'l', - 120262 => 'm', - 120263 => 'n', - 120264 => 'o', - 120265 => 'p', - 120266 => 'q', - 120267 => 'r', - 120268 => 's', - 120269 => 't', - 120270 => 'u', - 120271 => 'v', - 120272 => 'w', - 120273 => 'x', - 120274 => 'y', - 120275 => 'z', - 120276 => 'a', - 120277 => 'b', - 120278 => 'c', - 120279 => 'd', - 120280 => 'e', - 120281 => 'f', - 120282 => 'g', - 120283 => 'h', - 120284 => 'i', - 120285 => 'j', - 120286 => 'k', - 120287 => 'l', - 120288 => 'm', - 120289 => 'n', - 120290 => 'o', - 120291 => 'p', - 120292 => 'q', - 120293 => 'r', - 120294 => 's', - 120295 => 't', - 120296 => 'u', - 120297 => 'v', - 120298 => 'w', - 120299 => 'x', - 120300 => 'y', - 120301 => 'z', - 120302 => 'a', - 120303 => 'b', - 120304 => 'c', - 120305 => 'd', - 120306 => 'e', - 120307 => 'f', - 120308 => 'g', - 120309 => 'h', - 120310 => 'i', - 120311 => 'j', - 120312 => 'k', - 120313 => 'l', - 120314 => 'm', - 120315 => 'n', - 120316 => 'o', - 120317 => 'p', - 120318 => 'q', - 120319 => 'r', - 120320 => 's', - 120321 => 't', - 120322 => 'u', - 120323 => 'v', - 120324 => 'w', - 120325 => 'x', - 120326 => 'y', - 120327 => 'z', - 120328 => 'a', - 120329 => 'b', - 120330 => 'c', - 120331 => 'd', - 120332 => 'e', - 120333 => 'f', - 120334 => 'g', - 120335 => 'h', - 120336 => 'i', - 120337 => 'j', - 120338 => 'k', - 120339 => 'l', - 120340 => 'm', - 120341 => 'n', - 120342 => 'o', - 120343 => 'p', - 120344 => 'q', - 120345 => 'r', - 120346 => 's', - 120347 => 't', - 120348 => 'u', - 120349 => 'v', - 120350 => 'w', - 120351 => 'x', - 120352 => 'y', - 120353 => 'z', - 120354 => 'a', - 120355 => 'b', - 120356 => 'c', - 120357 => 'd', - 120358 => 'e', - 120359 => 'f', - 120360 => 'g', - 120361 => 'h', - 120362 => 'i', - 120363 => 'j', - 120364 => 'k', - 120365 => 'l', - 120366 => 'm', - 120367 => 'n', - 120368 => 'o', - 120369 => 'p', - 120370 => 'q', - 120371 => 'r', - 120372 => 's', - 120373 => 't', - 120374 => 'u', - 120375 => 'v', - 120376 => 'w', - 120377 => 'x', - 120378 => 'y', - 120379 => 'z', - 120380 => 'a', - 120381 => 'b', - 120382 => 'c', - 120383 => 'd', - 120384 => 'e', - 120385 => 'f', - 120386 => 'g', - 120387 => 'h', - 120388 => 'i', - 120389 => 'j', - 120390 => 'k', - 120391 => 'l', - 120392 => 'm', - 120393 => 'n', - 120394 => 'o', - 120395 => 'p', - 120396 => 'q', - 120397 => 'r', - 120398 => 's', - 120399 => 't', - 120400 => 'u', - 120401 => 'v', - 120402 => 'w', - 120403 => 'x', - 120404 => 'y', - 120405 => 'z', - 120406 => 'a', - 120407 => 'b', - 120408 => 'c', - 120409 => 'd', - 120410 => 'e', - 120411 => 'f', - 120412 => 'g', - 120413 => 'h', - 120414 => 'i', - 120415 => 'j', - 120416 => 'k', - 120417 => 'l', - 120418 => 'm', - 120419 => 'n', - 120420 => 'o', - 120421 => 'p', - 120422 => 'q', - 120423 => 'r', - 120424 => 's', - 120425 => 't', - 120426 => 'u', - 120427 => 'v', - 120428 => 'w', - 120429 => 'x', - 120430 => 'y', - 120431 => 'z', - 120432 => 'a', - 120433 => 'b', - 120434 => 'c', - 120435 => 'd', - 120436 => 'e', - 120437 => 'f', - 120438 => 'g', - 120439 => 'h', - 120440 => 'i', - 120441 => 'j', - 120442 => 'k', - 120443 => 'l', - 120444 => 'm', - 120445 => 'n', - 120446 => 'o', - 120447 => 'p', - 120448 => 'q', - 120449 => 'r', - 120450 => 's', - 120451 => 't', - 120452 => 'u', - 120453 => 'v', - 120454 => 'w', - 120455 => 'x', - 120456 => 'y', - 120457 => 'z', - 120458 => 'a', - 120459 => 'b', - 120460 => 'c', - 120461 => 'd', - 120462 => 'e', - 120463 => 'f', - 120464 => 'g', - 120465 => 'h', - 120466 => 'i', - 120467 => 'j', - 120468 => 'k', - 120469 => 'l', - 120470 => 'm', - 120471 => 'n', - 120472 => 'o', - 120473 => 'p', - 120474 => 'q', - 120475 => 'r', - 120476 => 's', - 120477 => 't', - 120478 => 'u', - 120479 => 'v', - 120480 => 'w', - 120481 => 'x', - 120482 => 'y', - 120483 => 'z', - 120484 => 'ı', - 120485 => 'ȷ', - 120488 => 'α', - 120489 => 'β', - 120490 => 'γ', - 120491 => 'δ', - 120492 => 'ε', - 120493 => 'ζ', - 120494 => 'η', - 120495 => 'θ', - 120496 => 'ι', - 120497 => 'κ', - 120498 => 'λ', - 120499 => 'μ', - 120500 => 'ν', - 120501 => 'ξ', - 120502 => 'ο', - 120503 => 'π', - 120504 => 'ρ', - 120505 => 'θ', - 120506 => 'σ', - 120507 => 'τ', - 120508 => 'υ', - 120509 => 'φ', - 120510 => 'χ', - 120511 => 'ψ', - 120512 => 'ω', - 120513 => '∇', - 120514 => 'α', - 120515 => 'β', - 120516 => 'γ', - 120517 => 'δ', - 120518 => 'ε', - 120519 => 'ζ', - 120520 => 'η', - 120521 => 'θ', - 120522 => 'ι', - 120523 => 'κ', - 120524 => 'λ', - 120525 => 'μ', - 120526 => 'ν', - 120527 => 'ξ', - 120528 => 'ο', - 120529 => 'π', - 120530 => 'ρ', - 120531 => 'σ', - 120532 => 'σ', - 120533 => 'τ', - 120534 => 'υ', - 120535 => 'φ', - 120536 => 'χ', - 120537 => 'ψ', - 120538 => 'ω', - 120539 => '∂', - 120540 => 'ε', - 120541 => 'θ', - 120542 => 'κ', - 120543 => 'φ', - 120544 => 'ρ', - 120545 => 'π', - 120546 => 'α', - 120547 => 'β', - 120548 => 'γ', - 120549 => 'δ', - 120550 => 'ε', - 120551 => 'ζ', - 120552 => 'η', - 120553 => 'θ', - 120554 => 'ι', - 120555 => 'κ', - 120556 => 'λ', - 120557 => 'μ', - 120558 => 'ν', - 120559 => 'ξ', - 120560 => 'ο', - 120561 => 'π', - 120562 => 'ρ', - 120563 => 'θ', - 120564 => 'σ', - 120565 => 'τ', - 120566 => 'υ', - 120567 => 'φ', - 120568 => 'χ', - 120569 => 'ψ', - 120570 => 'ω', - 120571 => '∇', - 120572 => 'α', - 120573 => 'β', - 120574 => 'γ', - 120575 => 'δ', - 120576 => 'ε', - 120577 => 'ζ', - 120578 => 'η', - 120579 => 'θ', - 120580 => 'ι', - 120581 => 'κ', - 120582 => 'λ', - 120583 => 'μ', - 120584 => 'ν', - 120585 => 'ξ', - 120586 => 'ο', - 120587 => 'π', - 120588 => 'ρ', - 120589 => 'σ', - 120590 => 'σ', - 120591 => 'τ', - 120592 => 'υ', - 120593 => 'φ', - 120594 => 'χ', - 120595 => 'ψ', - 120596 => 'ω', - 120597 => '∂', - 120598 => 'ε', - 120599 => 'θ', - 120600 => 'κ', - 120601 => 'φ', - 120602 => 'ρ', - 120603 => 'π', - 120604 => 'α', - 120605 => 'β', - 120606 => 'γ', - 120607 => 'δ', - 120608 => 'ε', - 120609 => 'ζ', - 120610 => 'η', - 120611 => 'θ', - 120612 => 'ι', - 120613 => 'κ', - 120614 => 'λ', - 120615 => 'μ', - 120616 => 'ν', - 120617 => 'ξ', - 120618 => 'ο', - 120619 => 'π', - 120620 => 'ρ', - 120621 => 'θ', - 120622 => 'σ', - 120623 => 'τ', - 120624 => 'υ', - 120625 => 'φ', - 120626 => 'χ', - 120627 => 'ψ', - 120628 => 'ω', - 120629 => '∇', - 120630 => 'α', - 120631 => 'β', - 120632 => 'γ', - 120633 => 'δ', - 120634 => 'ε', - 120635 => 'ζ', - 120636 => 'η', - 120637 => 'θ', - 120638 => 'ι', - 120639 => 'κ', - 120640 => 'λ', - 120641 => 'μ', - 120642 => 'ν', - 120643 => 'ξ', - 120644 => 'ο', - 120645 => 'π', - 120646 => 'ρ', - 120647 => 'σ', - 120648 => 'σ', - 120649 => 'τ', - 120650 => 'υ', - 120651 => 'φ', - 120652 => 'χ', - 120653 => 'ψ', - 120654 => 'ω', - 120655 => '∂', - 120656 => 'ε', - 120657 => 'θ', - 120658 => 'κ', - 120659 => 'φ', - 120660 => 'ρ', - 120661 => 'π', - 120662 => 'α', - 120663 => 'β', - 120664 => 'γ', - 120665 => 'δ', - 120666 => 'ε', - 120667 => 'ζ', - 120668 => 'η', - 120669 => 'θ', - 120670 => 'ι', - 120671 => 'κ', - 120672 => 'λ', - 120673 => 'μ', - 120674 => 'ν', - 120675 => 'ξ', - 120676 => 'ο', - 120677 => 'π', - 120678 => 'ρ', - 120679 => 'θ', - 120680 => 'σ', - 120681 => 'τ', - 120682 => 'υ', - 120683 => 'φ', - 120684 => 'χ', - 120685 => 'ψ', - 120686 => 'ω', - 120687 => '∇', - 120688 => 'α', - 120689 => 'β', - 120690 => 'γ', - 120691 => 'δ', - 120692 => 'ε', - 120693 => 'ζ', - 120694 => 'η', - 120695 => 'θ', - 120696 => 'ι', - 120697 => 'κ', - 120698 => 'λ', - 120699 => 'μ', - 120700 => 'ν', - 120701 => 'ξ', - 120702 => 'ο', - 120703 => 'π', - 120704 => 'ρ', - 120705 => 'σ', - 120706 => 'σ', - 120707 => 'τ', - 120708 => 'υ', - 120709 => 'φ', - 120710 => 'χ', - 120711 => 'ψ', - 120712 => 'ω', - 120713 => '∂', - 120714 => 'ε', - 120715 => 'θ', - 120716 => 'κ', - 120717 => 'φ', - 120718 => 'ρ', - 120719 => 'π', - 120720 => 'α', - 120721 => 'β', - 120722 => 'γ', - 120723 => 'δ', - 120724 => 'ε', - 120725 => 'ζ', - 120726 => 'η', - 120727 => 'θ', - 120728 => 'ι', - 120729 => 'κ', - 120730 => 'λ', - 120731 => 'μ', - 120732 => 'ν', - 120733 => 'ξ', - 120734 => 'ο', - 120735 => 'π', - 120736 => 'ρ', - 120737 => 'θ', - 120738 => 'σ', - 120739 => 'τ', - 120740 => 'υ', - 120741 => 'φ', - 120742 => 'χ', - 120743 => 'ψ', - 120744 => 'ω', - 120745 => '∇', - 120746 => 'α', - 120747 => 'β', - 120748 => 'γ', - 120749 => 'δ', - 120750 => 'ε', - 120751 => 'ζ', - 120752 => 'η', - 120753 => 'θ', - 120754 => 'ι', - 120755 => 'κ', - 120756 => 'λ', - 120757 => 'μ', - 120758 => 'ν', - 120759 => 'ξ', - 120760 => 'ο', - 120761 => 'π', - 120762 => 'ρ', - 120763 => 'σ', - 120764 => 'σ', - 120765 => 'τ', - 120766 => 'υ', - 120767 => 'φ', - 120768 => 'χ', - 120769 => 'ψ', - 120770 => 'ω', - 120771 => '∂', - 120772 => 'ε', - 120773 => 'θ', - 120774 => 'κ', - 120775 => 'φ', - 120776 => 'ρ', - 120777 => 'π', - 120778 => 'ϝ', - 120779 => 'ϝ', - 120782 => '0', - 120783 => '1', - 120784 => '2', - 120785 => '3', - 120786 => '4', - 120787 => '5', - 120788 => '6', - 120789 => '7', - 120790 => '8', - 120791 => '9', - 120792 => '0', - 120793 => '1', - 120794 => '2', - 120795 => '3', - 120796 => '4', - 120797 => '5', - 120798 => '6', - 120799 => '7', - 120800 => '8', - 120801 => '9', - 120802 => '0', - 120803 => '1', - 120804 => '2', - 120805 => '3', - 120806 => '4', - 120807 => '5', - 120808 => '6', - 120809 => '7', - 120810 => '8', - 120811 => '9', - 120812 => '0', - 120813 => '1', - 120814 => '2', - 120815 => '3', - 120816 => '4', - 120817 => '5', - 120818 => '6', - 120819 => '7', - 120820 => '8', - 120821 => '9', - 120822 => '0', - 120823 => '1', - 120824 => '2', - 120825 => '3', - 120826 => '4', - 120827 => '5', - 120828 => '6', - 120829 => '7', - 120830 => '8', - 120831 => '9', - 125184 => '𞤢', - 125185 => '𞤣', - 125186 => '𞤤', - 125187 => '𞤥', - 125188 => '𞤦', - 125189 => '𞤧', - 125190 => '𞤨', - 125191 => '𞤩', - 125192 => '𞤪', - 125193 => '𞤫', - 125194 => '𞤬', - 125195 => '𞤭', - 125196 => '𞤮', - 125197 => '𞤯', - 125198 => '𞤰', - 125199 => '𞤱', - 125200 => '𞤲', - 125201 => '𞤳', - 125202 => '𞤴', - 125203 => '𞤵', - 125204 => '𞤶', - 125205 => '𞤷', - 125206 => '𞤸', - 125207 => '𞤹', - 125208 => '𞤺', - 125209 => '𞤻', - 125210 => '𞤼', - 125211 => '𞤽', - 125212 => '𞤾', - 125213 => '𞤿', - 125214 => '𞥀', - 125215 => '𞥁', - 125216 => '𞥂', - 125217 => '𞥃', - 126464 => 'ا', - 126465 => 'ب', - 126466 => 'ج', - 126467 => 'د', - 126469 => 'و', - 126470 => 'ز', - 126471 => 'ح', - 126472 => 'ط', - 126473 => 'ي', - 126474 => 'ك', - 126475 => 'ل', - 126476 => 'م', - 126477 => 'ن', - 126478 => 'س', - 126479 => 'ع', - 126480 => 'ف', - 126481 => 'ص', - 126482 => 'ق', - 126483 => 'ر', - 126484 => 'ش', - 126485 => 'ت', - 126486 => 'ث', - 126487 => 'خ', - 126488 => 'ذ', - 126489 => 'ض', - 126490 => 'ظ', - 126491 => 'غ', - 126492 => 'ٮ', - 126493 => 'ں', - 126494 => 'ڡ', - 126495 => 'ٯ', - 126497 => 'ب', - 126498 => 'ج', - 126500 => 'ه', - 126503 => 'ح', - 126505 => 'ي', - 126506 => 'ك', - 126507 => 'ل', - 126508 => 'م', - 126509 => 'ن', - 126510 => 'س', - 126511 => 'ع', - 126512 => 'ف', - 126513 => 'ص', - 126514 => 'ق', - 126516 => 'ش', - 126517 => 'ت', - 126518 => 'ث', - 126519 => 'خ', - 126521 => 'ض', - 126523 => 'غ', - 126530 => 'ج', - 126535 => 'ح', - 126537 => 'ي', - 126539 => 'ل', - 126541 => 'ن', - 126542 => 'س', - 126543 => 'ع', - 126545 => 'ص', - 126546 => 'ق', - 126548 => 'ش', - 126551 => 'خ', - 126553 => 'ض', - 126555 => 'غ', - 126557 => 'ں', - 126559 => 'ٯ', - 126561 => 'ب', - 126562 => 'ج', - 126564 => 'ه', - 126567 => 'ح', - 126568 => 'ط', - 126569 => 'ي', - 126570 => 'ك', - 126572 => 'م', - 126573 => 'ن', - 126574 => 'س', - 126575 => 'ع', - 126576 => 'ف', - 126577 => 'ص', - 126578 => 'ق', - 126580 => 'ش', - 126581 => 'ت', - 126582 => 'ث', - 126583 => 'خ', - 126585 => 'ض', - 126586 => 'ظ', - 126587 => 'غ', - 126588 => 'ٮ', - 126590 => 'ڡ', - 126592 => 'ا', - 126593 => 'ب', - 126594 => 'ج', - 126595 => 'د', - 126596 => 'ه', - 126597 => 'و', - 126598 => 'ز', - 126599 => 'ح', - 126600 => 'ط', - 126601 => 'ي', - 126603 => 'ل', - 126604 => 'م', - 126605 => 'ن', - 126606 => 'س', - 126607 => 'ع', - 126608 => 'ف', - 126609 => 'ص', - 126610 => 'ق', - 126611 => 'ر', - 126612 => 'ش', - 126613 => 'ت', - 126614 => 'ث', - 126615 => 'خ', - 126616 => 'ذ', - 126617 => 'ض', - 126618 => 'ظ', - 126619 => 'غ', - 126625 => 'ب', - 126626 => 'ج', - 126627 => 'د', - 126629 => 'و', - 126630 => 'ز', - 126631 => 'ح', - 126632 => 'ط', - 126633 => 'ي', - 126635 => 'ل', - 126636 => 'م', - 126637 => 'ن', - 126638 => 'س', - 126639 => 'ع', - 126640 => 'ف', - 126641 => 'ص', - 126642 => 'ق', - 126643 => 'ر', - 126644 => 'ش', - 126645 => 'ت', - 126646 => 'ث', - 126647 => 'خ', - 126648 => 'ذ', - 126649 => 'ض', - 126650 => 'ظ', - 126651 => 'غ', - 127274 => '〔s〕', - 127275 => 'c', - 127276 => 'r', - 127277 => 'cd', - 127278 => 'wz', - 127280 => 'a', - 127281 => 'b', - 127282 => 'c', - 127283 => 'd', - 127284 => 'e', - 127285 => 'f', - 127286 => 'g', - 127287 => 'h', - 127288 => 'i', - 127289 => 'j', - 127290 => 'k', - 127291 => 'l', - 127292 => 'm', - 127293 => 'n', - 127294 => 'o', - 127295 => 'p', - 127296 => 'q', - 127297 => 'r', - 127298 => 's', - 127299 => 't', - 127300 => 'u', - 127301 => 'v', - 127302 => 'w', - 127303 => 'x', - 127304 => 'y', - 127305 => 'z', - 127306 => 'hv', - 127307 => 'mv', - 127308 => 'sd', - 127309 => 'ss', - 127310 => 'ppv', - 127311 => 'wc', - 127338 => 'mc', - 127339 => 'md', - 127340 => 'mr', - 127376 => 'dj', - 127488 => 'ほか', - 127489 => 'ココ', - 127490 => 'サ', - 127504 => '手', - 127505 => '字', - 127506 => '双', - 127507 => 'デ', - 127508 => '二', - 127509 => '多', - 127510 => '解', - 127511 => '天', - 127512 => '交', - 127513 => '映', - 127514 => '無', - 127515 => '料', - 127516 => '前', - 127517 => '後', - 127518 => '再', - 127519 => '新', - 127520 => '初', - 127521 => '終', - 127522 => '生', - 127523 => '販', - 127524 => '声', - 127525 => '吹', - 127526 => '演', - 127527 => '投', - 127528 => '捕', - 127529 => '一', - 127530 => '三', - 127531 => '遊', - 127532 => '左', - 127533 => '中', - 127534 => '右', - 127535 => '指', - 127536 => '走', - 127537 => '打', - 127538 => '禁', - 127539 => '空', - 127540 => '合', - 127541 => '満', - 127542 => '有', - 127543 => '月', - 127544 => '申', - 127545 => '割', - 127546 => '営', - 127547 => '配', - 127552 => '〔本〕', - 127553 => '〔三〕', - 127554 => '〔二〕', - 127555 => '〔安〕', - 127556 => '〔点〕', - 127557 => '〔打〕', - 127558 => '〔盗〕', - 127559 => '〔勝〕', - 127560 => '〔敗〕', - 127568 => '得', - 127569 => '可', - 130032 => '0', - 130033 => '1', - 130034 => '2', - 130035 => '3', - 130036 => '4', - 130037 => '5', - 130038 => '6', - 130039 => '7', - 130040 => '8', - 130041 => '9', - 194560 => '丽', - 194561 => '丸', - 194562 => '乁', - 194563 => '𠄢', - 194564 => '你', - 194565 => '侮', - 194566 => '侻', - 194567 => '倂', - 194568 => '偺', - 194569 => '備', - 194570 => '僧', - 194571 => '像', - 194572 => '㒞', - 194573 => '𠘺', - 194574 => '免', - 194575 => '兔', - 194576 => '兤', - 194577 => '具', - 194578 => '𠔜', - 194579 => '㒹', - 194580 => '內', - 194581 => '再', - 194582 => '𠕋', - 194583 => '冗', - 194584 => '冤', - 194585 => '仌', - 194586 => '冬', - 194587 => '况', - 194588 => '𩇟', - 194589 => '凵', - 194590 => '刃', - 194591 => '㓟', - 194592 => '刻', - 194593 => '剆', - 194594 => '割', - 194595 => '剷', - 194596 => '㔕', - 194597 => '勇', - 194598 => '勉', - 194599 => '勤', - 194600 => '勺', - 194601 => '包', - 194602 => '匆', - 194603 => '北', - 194604 => '卉', - 194605 => '卑', - 194606 => '博', - 194607 => '即', - 194608 => '卽', - 194609 => '卿', - 194610 => '卿', - 194611 => '卿', - 194612 => '𠨬', - 194613 => '灰', - 194614 => '及', - 194615 => '叟', - 194616 => '𠭣', - 194617 => '叫', - 194618 => '叱', - 194619 => '吆', - 194620 => '咞', - 194621 => '吸', - 194622 => '呈', - 194623 => '周', - 194624 => '咢', - 194625 => '哶', - 194626 => '唐', - 194627 => '啓', - 194628 => '啣', - 194629 => '善', - 194630 => '善', - 194631 => '喙', - 194632 => '喫', - 194633 => '喳', - 194634 => '嗂', - 194635 => '圖', - 194636 => '嘆', - 194637 => '圗', - 194638 => '噑', - 194639 => '噴', - 194640 => '切', - 194641 => '壮', - 194642 => '城', - 194643 => '埴', - 194644 => '堍', - 194645 => '型', - 194646 => '堲', - 194647 => '報', - 194648 => '墬', - 194649 => '𡓤', - 194650 => '売', - 194651 => '壷', - 194652 => '夆', - 194653 => '多', - 194654 => '夢', - 194655 => '奢', - 194656 => '𡚨', - 194657 => '𡛪', - 194658 => '姬', - 194659 => '娛', - 194660 => '娧', - 194661 => '姘', - 194662 => '婦', - 194663 => '㛮', - 194665 => '嬈', - 194666 => '嬾', - 194667 => '嬾', - 194668 => '𡧈', - 194669 => '寃', - 194670 => '寘', - 194671 => '寧', - 194672 => '寳', - 194673 => '𡬘', - 194674 => '寿', - 194675 => '将', - 194677 => '尢', - 194678 => '㞁', - 194679 => '屠', - 194680 => '屮', - 194681 => '峀', - 194682 => '岍', - 194683 => '𡷤', - 194684 => '嵃', - 194685 => '𡷦', - 194686 => '嵮', - 194687 => '嵫', - 194688 => '嵼', - 194689 => '巡', - 194690 => '巢', - 194691 => '㠯', - 194692 => '巽', - 194693 => '帨', - 194694 => '帽', - 194695 => '幩', - 194696 => '㡢', - 194697 => '𢆃', - 194698 => '㡼', - 194699 => '庰', - 194700 => '庳', - 194701 => '庶', - 194702 => '廊', - 194703 => '𪎒', - 194704 => '廾', - 194705 => '𢌱', - 194706 => '𢌱', - 194707 => '舁', - 194708 => '弢', - 194709 => '弢', - 194710 => '㣇', - 194711 => '𣊸', - 194712 => '𦇚', - 194713 => '形', - 194714 => '彫', - 194715 => '㣣', - 194716 => '徚', - 194717 => '忍', - 194718 => '志', - 194719 => '忹', - 194720 => '悁', - 194721 => '㤺', - 194722 => '㤜', - 194723 => '悔', - 194724 => '𢛔', - 194725 => '惇', - 194726 => '慈', - 194727 => '慌', - 194728 => '慎', - 194729 => '慌', - 194730 => '慺', - 194731 => '憎', - 194732 => '憲', - 194733 => '憤', - 194734 => '憯', - 194735 => '懞', - 194736 => '懲', - 194737 => '懶', - 194738 => '成', - 194739 => '戛', - 194740 => '扝', - 194741 => '抱', - 194742 => '拔', - 194743 => '捐', - 194744 => '𢬌', - 194745 => '挽', - 194746 => '拼', - 194747 => '捨', - 194748 => '掃', - 194749 => '揤', - 194750 => '𢯱', - 194751 => '搢', - 194752 => '揅', - 194753 => '掩', - 194754 => '㨮', - 194755 => '摩', - 194756 => '摾', - 194757 => '撝', - 194758 => '摷', - 194759 => '㩬', - 194760 => '敏', - 194761 => '敬', - 194762 => '𣀊', - 194763 => '旣', - 194764 => '書', - 194765 => '晉', - 194766 => '㬙', - 194767 => '暑', - 194768 => '㬈', - 194769 => '㫤', - 194770 => '冒', - 194771 => '冕', - 194772 => '最', - 194773 => '暜', - 194774 => '肭', - 194775 => '䏙', - 194776 => '朗', - 194777 => '望', - 194778 => '朡', - 194779 => '杞', - 194780 => '杓', - 194781 => '𣏃', - 194782 => '㭉', - 194783 => '柺', - 194784 => '枅', - 194785 => '桒', - 194786 => '梅', - 194787 => '𣑭', - 194788 => '梎', - 194789 => '栟', - 194790 => '椔', - 194791 => '㮝', - 194792 => '楂', - 194793 => '榣', - 194794 => '槪', - 194795 => '檨', - 194796 => '𣚣', - 194797 => '櫛', - 194798 => '㰘', - 194799 => '次', - 194800 => '𣢧', - 194801 => '歔', - 194802 => '㱎', - 194803 => '歲', - 194804 => '殟', - 194805 => '殺', - 194806 => '殻', - 194807 => '𣪍', - 194808 => '𡴋', - 194809 => '𣫺', - 194810 => '汎', - 194811 => '𣲼', - 194812 => '沿', - 194813 => '泍', - 194814 => '汧', - 194815 => '洖', - 194816 => '派', - 194817 => '海', - 194818 => '流', - 194819 => '浩', - 194820 => '浸', - 194821 => '涅', - 194822 => '𣴞', - 194823 => '洴', - 194824 => '港', - 194825 => '湮', - 194826 => '㴳', - 194827 => '滋', - 194828 => '滇', - 194829 => '𣻑', - 194830 => '淹', - 194831 => '潮', - 194832 => '𣽞', - 194833 => '𣾎', - 194834 => '濆', - 194835 => '瀹', - 194836 => '瀞', - 194837 => '瀛', - 194838 => '㶖', - 194839 => '灊', - 194840 => '災', - 194841 => '灷', - 194842 => '炭', - 194843 => '𠔥', - 194844 => '煅', - 194845 => '𤉣', - 194846 => '熜', - 194848 => '爨', - 194849 => '爵', - 194850 => '牐', - 194851 => '𤘈', - 194852 => '犀', - 194853 => '犕', - 194854 => '𤜵', - 194855 => '𤠔', - 194856 => '獺', - 194857 => '王', - 194858 => '㺬', - 194859 => '玥', - 194860 => '㺸', - 194861 => '㺸', - 194862 => '瑇', - 194863 => '瑜', - 194864 => '瑱', - 194865 => '璅', - 194866 => '瓊', - 194867 => '㼛', - 194868 => '甤', - 194869 => '𤰶', - 194870 => '甾', - 194871 => '𤲒', - 194872 => '異', - 194873 => '𢆟', - 194874 => '瘐', - 194875 => '𤾡', - 194876 => '𤾸', - 194877 => '𥁄', - 194878 => '㿼', - 194879 => '䀈', - 194880 => '直', - 194881 => '𥃳', - 194882 => '𥃲', - 194883 => '𥄙', - 194884 => '𥄳', - 194885 => '眞', - 194886 => '真', - 194887 => '真', - 194888 => '睊', - 194889 => '䀹', - 194890 => '瞋', - 194891 => '䁆', - 194892 => '䂖', - 194893 => '𥐝', - 194894 => '硎', - 194895 => '碌', - 194896 => '磌', - 194897 => '䃣', - 194898 => '𥘦', - 194899 => '祖', - 194900 => '𥚚', - 194901 => '𥛅', - 194902 => '福', - 194903 => '秫', - 194904 => '䄯', - 194905 => '穀', - 194906 => '穊', - 194907 => '穏', - 194908 => '𥥼', - 194909 => '𥪧', - 194910 => '𥪧', - 194912 => '䈂', - 194913 => '𥮫', - 194914 => '篆', - 194915 => '築', - 194916 => '䈧', - 194917 => '𥲀', - 194918 => '糒', - 194919 => '䊠', - 194920 => '糨', - 194921 => '糣', - 194922 => '紀', - 194923 => '𥾆', - 194924 => '絣', - 194925 => '䌁', - 194926 => '緇', - 194927 => '縂', - 194928 => '繅', - 194929 => '䌴', - 194930 => '𦈨', - 194931 => '𦉇', - 194932 => '䍙', - 194933 => '𦋙', - 194934 => '罺', - 194935 => '𦌾', - 194936 => '羕', - 194937 => '翺', - 194938 => '者', - 194939 => '𦓚', - 194940 => '𦔣', - 194941 => '聠', - 194942 => '𦖨', - 194943 => '聰', - 194944 => '𣍟', - 194945 => '䏕', - 194946 => '育', - 194947 => '脃', - 194948 => '䐋', - 194949 => '脾', - 194950 => '媵', - 194951 => '𦞧', - 194952 => '𦞵', - 194953 => '𣎓', - 194954 => '𣎜', - 194955 => '舁', - 194956 => '舄', - 194957 => '辞', - 194958 => '䑫', - 194959 => '芑', - 194960 => '芋', - 194961 => '芝', - 194962 => '劳', - 194963 => '花', - 194964 => '芳', - 194965 => '芽', - 194966 => '苦', - 194967 => '𦬼', - 194968 => '若', - 194969 => '茝', - 194970 => '荣', - 194971 => '莭', - 194972 => '茣', - 194973 => '莽', - 194974 => '菧', - 194975 => '著', - 194976 => '荓', - 194977 => '菊', - 194978 => '菌', - 194979 => '菜', - 194980 => '𦰶', - 194981 => '𦵫', - 194982 => '𦳕', - 194983 => '䔫', - 194984 => '蓱', - 194985 => '蓳', - 194986 => '蔖', - 194987 => '𧏊', - 194988 => '蕤', - 194989 => '𦼬', - 194990 => '䕝', - 194991 => '䕡', - 194992 => '𦾱', - 194993 => '𧃒', - 194994 => '䕫', - 194995 => '虐', - 194996 => '虜', - 194997 => '虧', - 194998 => '虩', - 194999 => '蚩', - 195000 => '蚈', - 195001 => '蜎', - 195002 => '蛢', - 195003 => '蝹', - 195004 => '蜨', - 195005 => '蝫', - 195006 => '螆', - 195008 => '蟡', - 195009 => '蠁', - 195010 => '䗹', - 195011 => '衠', - 195012 => '衣', - 195013 => '𧙧', - 195014 => '裗', - 195015 => '裞', - 195016 => '䘵', - 195017 => '裺', - 195018 => '㒻', - 195019 => '𧢮', - 195020 => '𧥦', - 195021 => '䚾', - 195022 => '䛇', - 195023 => '誠', - 195024 => '諭', - 195025 => '變', - 195026 => '豕', - 195027 => '𧲨', - 195028 => '貫', - 195029 => '賁', - 195030 => '贛', - 195031 => '起', - 195032 => '𧼯', - 195033 => '𠠄', - 195034 => '跋', - 195035 => '趼', - 195036 => '跰', - 195037 => '𠣞', - 195038 => '軔', - 195039 => '輸', - 195040 => '𨗒', - 195041 => '𨗭', - 195042 => '邔', - 195043 => '郱', - 195044 => '鄑', - 195045 => '𨜮', - 195046 => '鄛', - 195047 => '鈸', - 195048 => '鋗', - 195049 => '鋘', - 195050 => '鉼', - 195051 => '鏹', - 195052 => '鐕', - 195053 => '𨯺', - 195054 => '開', - 195055 => '䦕', - 195056 => '閷', - 195057 => '𨵷', - 195058 => '䧦', - 195059 => '雃', - 195060 => '嶲', - 195061 => '霣', - 195062 => '𩅅', - 195063 => '𩈚', - 195064 => '䩮', - 195065 => '䩶', - 195066 => '韠', - 195067 => '𩐊', - 195068 => '䪲', - 195069 => '𩒖', - 195070 => '頋', - 195071 => '頋', - 195072 => '頩', - 195073 => '𩖶', - 195074 => '飢', - 195075 => '䬳', - 195076 => '餩', - 195077 => '馧', - 195078 => '駂', - 195079 => '駾', - 195080 => '䯎', - 195081 => '𩬰', - 195082 => '鬒', - 195083 => '鱀', - 195084 => '鳽', - 195085 => '䳎', - 195086 => '䳭', - 195087 => '鵧', - 195088 => '𪃎', - 195089 => '䳸', - 195090 => '𪄅', - 195091 => '𪈎', - 195092 => '𪊑', - 195093 => '麻', - 195094 => '䵖', - 195095 => '黹', - 195096 => '黾', - 195097 => '鼅', - 195098 => '鼏', - 195099 => '鼖', - 195100 => '鼻', - 195101 => '𪘀', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/virama.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/virama.php deleted file mode 100644 index 1958e37ed..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/Resources/unidata/virama.php +++ /dev/null @@ -1,65 +0,0 @@ - 9, - 2509 => 9, - 2637 => 9, - 2765 => 9, - 2893 => 9, - 3021 => 9, - 3149 => 9, - 3277 => 9, - 3387 => 9, - 3388 => 9, - 3405 => 9, - 3530 => 9, - 3642 => 9, - 3770 => 9, - 3972 => 9, - 4153 => 9, - 4154 => 9, - 5908 => 9, - 5940 => 9, - 6098 => 9, - 6752 => 9, - 6980 => 9, - 7082 => 9, - 7083 => 9, - 7154 => 9, - 7155 => 9, - 11647 => 9, - 43014 => 9, - 43052 => 9, - 43204 => 9, - 43347 => 9, - 43456 => 9, - 43766 => 9, - 44013 => 9, - 68159 => 9, - 69702 => 9, - 69759 => 9, - 69817 => 9, - 69939 => 9, - 69940 => 9, - 70080 => 9, - 70197 => 9, - 70378 => 9, - 70477 => 9, - 70722 => 9, - 70850 => 9, - 71103 => 9, - 71231 => 9, - 71350 => 9, - 71467 => 9, - 71737 => 9, - 71997 => 9, - 71998 => 9, - 72160 => 9, - 72244 => 9, - 72263 => 9, - 72345 => 9, - 72767 => 9, - 73028 => 9, - 73029 => 9, - 73111 => 9, -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap.php deleted file mode 100644 index 57c78356c..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap.php +++ /dev/null @@ -1,145 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Idn as p; - -if (extension_loaded('intl')) { - return; -} - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!defined('U_IDNA_PROHIBITED_ERROR')) { - define('U_IDNA_PROHIBITED_ERROR', 66560); -} -if (!defined('U_IDNA_ERROR_START')) { - define('U_IDNA_ERROR_START', 66560); -} -if (!defined('U_IDNA_UNASSIGNED_ERROR')) { - define('U_IDNA_UNASSIGNED_ERROR', 66561); -} -if (!defined('U_IDNA_CHECK_BIDI_ERROR')) { - define('U_IDNA_CHECK_BIDI_ERROR', 66562); -} -if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { - define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); -} -if (!defined('U_IDNA_ACE_PREFIX_ERROR')) { - define('U_IDNA_ACE_PREFIX_ERROR', 66564); -} -if (!defined('U_IDNA_VERIFICATION_ERROR')) { - define('U_IDNA_VERIFICATION_ERROR', 66565); -} -if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { - define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); -} -if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { - define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); -} -if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { - define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); -} -if (!defined('U_IDNA_ERROR_LIMIT')) { - define('U_IDNA_ERROR_LIMIT', 66569); -} -if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) { - define('U_STRINGPREP_PROHIBITED_ERROR', 66560); -} -if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) { - define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); -} -if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { - define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); -} -if (!defined('IDNA_DEFAULT')) { - define('IDNA_DEFAULT', 0); -} -if (!defined('IDNA_ALLOW_UNASSIGNED')) { - define('IDNA_ALLOW_UNASSIGNED', 1); -} -if (!defined('IDNA_USE_STD3_RULES')) { - define('IDNA_USE_STD3_RULES', 2); -} -if (!defined('IDNA_CHECK_BIDI')) { - define('IDNA_CHECK_BIDI', 4); -} -if (!defined('IDNA_CHECK_CONTEXTJ')) { - define('IDNA_CHECK_CONTEXTJ', 8); -} -if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { - define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); -} -if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { - define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); -} -if (!defined('INTL_IDNA_VARIANT_2003')) { - define('INTL_IDNA_VARIANT_2003', 0); -} -if (!defined('INTL_IDNA_VARIANT_UTS46')) { - define('INTL_IDNA_VARIANT_UTS46', 1); -} -if (!defined('IDNA_ERROR_EMPTY_LABEL')) { - define('IDNA_ERROR_EMPTY_LABEL', 1); -} -if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) { - define('IDNA_ERROR_LABEL_TOO_LONG', 2); -} -if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { - define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); -} -if (!defined('IDNA_ERROR_LEADING_HYPHEN')) { - define('IDNA_ERROR_LEADING_HYPHEN', 8); -} -if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) { - define('IDNA_ERROR_TRAILING_HYPHEN', 16); -} -if (!defined('IDNA_ERROR_HYPHEN_3_4')) { - define('IDNA_ERROR_HYPHEN_3_4', 32); -} -if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { - define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); -} -if (!defined('IDNA_ERROR_DISALLOWED')) { - define('IDNA_ERROR_DISALLOWED', 128); -} -if (!defined('IDNA_ERROR_PUNYCODE')) { - define('IDNA_ERROR_PUNYCODE', 256); -} -if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) { - define('IDNA_ERROR_LABEL_HAS_DOT', 512); -} -if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) { - define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); -} -if (!defined('IDNA_ERROR_BIDI')) { - define('IDNA_ERROR_BIDI', 2048); -} -if (!defined('IDNA_ERROR_CONTEXTJ')) { - define('IDNA_ERROR_CONTEXTJ', 4096); -} - -if (\PHP_VERSION_ID < 70400) { - if (!function_exists('idn_to_ascii')) { - function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } - } - if (!function_exists('idn_to_utf8')) { - function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } - } -} else { - if (!function_exists('idn_to_ascii')) { - function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } - } - if (!function_exists('idn_to_utf8')) { - function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap80.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap80.php deleted file mode 100644 index a62c2d69b..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/bootstrap80.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Idn as p; - -if (!defined('U_IDNA_PROHIBITED_ERROR')) { - define('U_IDNA_PROHIBITED_ERROR', 66560); -} -if (!defined('U_IDNA_ERROR_START')) { - define('U_IDNA_ERROR_START', 66560); -} -if (!defined('U_IDNA_UNASSIGNED_ERROR')) { - define('U_IDNA_UNASSIGNED_ERROR', 66561); -} -if (!defined('U_IDNA_CHECK_BIDI_ERROR')) { - define('U_IDNA_CHECK_BIDI_ERROR', 66562); -} -if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { - define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); -} -if (!defined('U_IDNA_ACE_PREFIX_ERROR')) { - define('U_IDNA_ACE_PREFIX_ERROR', 66564); -} -if (!defined('U_IDNA_VERIFICATION_ERROR')) { - define('U_IDNA_VERIFICATION_ERROR', 66565); -} -if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { - define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); -} -if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { - define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); -} -if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { - define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); -} -if (!defined('U_IDNA_ERROR_LIMIT')) { - define('U_IDNA_ERROR_LIMIT', 66569); -} -if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) { - define('U_STRINGPREP_PROHIBITED_ERROR', 66560); -} -if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) { - define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); -} -if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { - define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); -} -if (!defined('IDNA_DEFAULT')) { - define('IDNA_DEFAULT', 0); -} -if (!defined('IDNA_ALLOW_UNASSIGNED')) { - define('IDNA_ALLOW_UNASSIGNED', 1); -} -if (!defined('IDNA_USE_STD3_RULES')) { - define('IDNA_USE_STD3_RULES', 2); -} -if (!defined('IDNA_CHECK_BIDI')) { - define('IDNA_CHECK_BIDI', 4); -} -if (!defined('IDNA_CHECK_CONTEXTJ')) { - define('IDNA_CHECK_CONTEXTJ', 8); -} -if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { - define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); -} -if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { - define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); -} -if (!defined('INTL_IDNA_VARIANT_UTS46')) { - define('INTL_IDNA_VARIANT_UTS46', 1); -} -if (!defined('IDNA_ERROR_EMPTY_LABEL')) { - define('IDNA_ERROR_EMPTY_LABEL', 1); -} -if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) { - define('IDNA_ERROR_LABEL_TOO_LONG', 2); -} -if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { - define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); -} -if (!defined('IDNA_ERROR_LEADING_HYPHEN')) { - define('IDNA_ERROR_LEADING_HYPHEN', 8); -} -if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) { - define('IDNA_ERROR_TRAILING_HYPHEN', 16); -} -if (!defined('IDNA_ERROR_HYPHEN_3_4')) { - define('IDNA_ERROR_HYPHEN_3_4', 32); -} -if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { - define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); -} -if (!defined('IDNA_ERROR_DISALLOWED')) { - define('IDNA_ERROR_DISALLOWED', 128); -} -if (!defined('IDNA_ERROR_PUNYCODE')) { - define('IDNA_ERROR_PUNYCODE', 256); -} -if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) { - define('IDNA_ERROR_LABEL_HAS_DOT', 512); -} -if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) { - define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); -} -if (!defined('IDNA_ERROR_BIDI')) { - define('IDNA_ERROR_BIDI', 2048); -} -if (!defined('IDNA_ERROR_CONTEXTJ')) { - define('IDNA_ERROR_CONTEXTJ', 4096); -} - -if (!function_exists('idn_to_ascii')) { - function idn_to_ascii(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); } -} -if (!function_exists('idn_to_utf8')) { - function idn_to_utf8(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/composer.json b/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/composer.json deleted file mode 100644 index 78e478ee8..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-idn/composer.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "symfony/polyfill-intl-idn", - "type": "library", - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "idn"], - "homepage": "https://symfony.com", - "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" - } - ], - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, - "files": [ "bootstrap.php" ] - }, - "suggest": { - "ext-intl": "For best performance" - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/LICENSE b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/LICENSE deleted file mode 100644 index 6e3afce69..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-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/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Normalizer.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Normalizer.php deleted file mode 100644 index 81704ab37..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Normalizer.php +++ /dev/null @@ -1,310 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Normalizer; - -/** - * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension. - * - * It has been validated with Unicode 6.3 Normalization Conformance Test. - * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations. - * - * @author Nicolas Grekas - * - * @internal - */ -class Normalizer -{ - public const FORM_D = \Normalizer::FORM_D; - public const FORM_KD = \Normalizer::FORM_KD; - public const FORM_C = \Normalizer::FORM_C; - public const FORM_KC = \Normalizer::FORM_KC; - public const NFD = \Normalizer::NFD; - public const NFKD = \Normalizer::NFKD; - public const NFC = \Normalizer::NFC; - public const NFKC = \Normalizer::NFKC; - - private static $C; - private static $D; - private static $KD; - private static $cC; - private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; - private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; - - public static function isNormalized(string $s, int $form = self::FORM_C) - { - if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) { - return false; - } - if (!isset($s[strspn($s, self::$ASCII)])) { - return true; - } - if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) { - return true; - } - - return self::normalize($s, $form) === $s; - } - - public static function normalize(string $s, int $form = self::FORM_C) - { - if (!preg_match('//u', $s)) { - return false; - } - - switch ($form) { - case self::NFC: $C = true; $K = false; break; - case self::NFD: $C = false; $K = false; break; - case self::NFKC: $C = true; $K = true; break; - case self::NFKD: $C = false; $K = true; break; - default: - if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) { - return $s; - } - - if (80000 > \PHP_VERSION_ID) { - return false; - } - - throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form'); - } - - if ('' === $s) { - return ''; - } - - if ($K && null === self::$KD) { - self::$KD = self::getData('compatibilityDecomposition'); - } - - if (null === self::$D) { - self::$D = self::getData('canonicalDecomposition'); - self::$cC = self::getData('combiningClass'); - } - - if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) \ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) { - mb_internal_encoding('8bit'); - } - - $r = self::decompose($s, $K); - - if ($C) { - if (null === self::$C) { - self::$C = self::getData('canonicalComposition'); - } - - $r = self::recompose($r); - } - if (null !== $mbEncoding) { - mb_internal_encoding($mbEncoding); - } - - return $r; - } - - private static function recompose($s) - { - $ASCII = self::$ASCII; - $compMap = self::$C; - $combClass = self::$cC; - $ulenMask = self::$ulenMask; - - $result = $tail = ''; - - $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"]; - $len = \strlen($s); - - $lastUchr = substr($s, 0, $i); - $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0; - - while ($i < $len) { - if ($s[$i] < "\x80") { - // ASCII chars - - if ($tail) { - $lastUchr .= $tail; - $tail = ''; - } - - if ($j = strspn($s, $ASCII, $i + 1)) { - $lastUchr .= substr($s, $i, $j); - $i += $j; - } - - $result .= $lastUchr; - $lastUchr = $s[$i]; - $lastUcls = 0; - ++$i; - continue; - } - - $ulen = $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - - if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr - || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr - || $lastUcls) { - // Table lookup and combining chars composition - - $ucls = $combClass[$uchr] ?? 0; - - if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) { - $lastUchr = $compMap[$lastUchr.$uchr]; - } elseif ($lastUcls = $ucls) { - $tail .= $uchr; - } else { - if ($tail) { - $lastUchr .= $tail; - $tail = ''; - } - - $result .= $lastUchr; - $lastUchr = $uchr; - } - } else { - // Hangul chars - - $L = \ord($lastUchr[2]) - 0x80; - $V = \ord($uchr[2]) - 0xA1; - $T = 0; - - $uchr = substr($s, $i + $ulen, 3); - - if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") { - $T = \ord($uchr[2]) - 0xA7; - 0 > $T && $T += 0x40; - $ulen += 3; - } - - $L = 0xAC00 + ($L * 21 + $V) * 28 + $T; - $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F); - } - - $i += $ulen; - } - - return $result.$lastUchr.$tail; - } - - private static function decompose($s, $c) - { - $result = ''; - - $ASCII = self::$ASCII; - $decompMap = self::$D; - $combClass = self::$cC; - $ulenMask = self::$ulenMask; - if ($c) { - $compatMap = self::$KD; - } - - $c = []; - $i = 0; - $len = \strlen($s); - - while ($i < $len) { - if ($s[$i] < "\x80") { - // ASCII chars - - if ($c) { - ksort($c); - $result .= implode('', $c); - $c = []; - } - - $j = 1 + strspn($s, $ASCII, $i + 1); - $result .= substr($s, $i, $j); - $i += $j; - continue; - } - - $ulen = $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - $i += $ulen; - - if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) { - // Table lookup - - if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) { - $uchr = $j; - - $j = \strlen($uchr); - $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"]; - - if ($ulen != $j) { - // Put trailing chars in $s - - $j -= $ulen; - $i -= $j; - - if (0 > $i) { - $s = str_repeat(' ', -$i).$s; - $len -= $i; - $i = 0; - } - - while ($j--) { - $s[$i + $j] = $uchr[$ulen + $j]; - } - - $uchr = substr($uchr, 0, $ulen); - } - } - if (isset($combClass[$uchr])) { - // Combining chars, for sorting - - if (!isset($c[$combClass[$uchr]])) { - $c[$combClass[$uchr]] = ''; - } - $c[$combClass[$uchr]] .= $uchr; - continue; - } - } else { - // Hangul chars - - $uchr = unpack('C*', $uchr); - $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80; - - $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588)) - ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28)); - - if ($j %= 28) { - $uchr .= $j < 25 - ? ("\xE1\x86".\chr(0xA7 + $j)) - : ("\xE1\x87".\chr(0x67 + $j)); - } - } - if ($c) { - ksort($c); - $result .= implode('', $c); - $c = []; - } - - $result .= $uchr; - } - - if ($c) { - ksort($c); - $result .= implode('', $c); - } - - return $result; - } - - private static function getData($file) - { - if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { - return require $file; - } - - return false; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/README.md b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/README.md deleted file mode 100644 index b9b762e85..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/README.md +++ /dev/null @@ -1,14 +0,0 @@ -Symfony Polyfill / Intl: Normalizer -=================================== - -This component provides a fallback implementation for the -[`Normalizer`](https://php.net/Normalizer) class provided -by the [Intl](https://php.net/intl) extension. - -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/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php deleted file mode 100644 index 0fdfc890a..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php +++ /dev/null @@ -1,17 +0,0 @@ - 'À', - 'Á' => 'Á', - 'Â' => 'Â', - 'Ã' => 'Ã', - 'Ä' => 'Ä', - 'Å' => 'Å', - 'Ç' => 'Ç', - 'È' => 'È', - 'É' => 'É', - 'Ê' => 'Ê', - 'Ë' => 'Ë', - 'Ì' => 'Ì', - 'Í' => 'Í', - 'Î' => 'Î', - 'Ï' => 'Ï', - 'Ñ' => 'Ñ', - 'Ò' => 'Ò', - 'Ó' => 'Ó', - 'Ô' => 'Ô', - 'Õ' => 'Õ', - 'Ö' => 'Ö', - 'Ù' => 'Ù', - 'Ú' => 'Ú', - 'Û' => 'Û', - 'Ü' => 'Ü', - 'Ý' => 'Ý', - 'à' => 'à', - 'á' => 'á', - 'â' => 'â', - 'ã' => 'ã', - 'ä' => 'ä', - 'å' => 'å', - 'ç' => 'ç', - 'è' => 'è', - 'é' => 'é', - 'ê' => 'ê', - 'ë' => 'ë', - 'ì' => 'ì', - 'í' => 'í', - 'î' => 'î', - 'ï' => 'ï', - 'ñ' => 'ñ', - 'ò' => 'ò', - 'ó' => 'ó', - 'ô' => 'ô', - 'õ' => 'õ', - 'ö' => 'ö', - 'ù' => 'ù', - 'ú' => 'ú', - 'û' => 'û', - 'ü' => 'ü', - 'ý' => 'ý', - 'ÿ' => 'ÿ', - 'Ā' => 'Ā', - 'ā' => 'ā', - 'Ă' => 'Ă', - 'ă' => 'ă', - 'Ą' => 'Ą', - 'ą' => 'ą', - 'Ć' => 'Ć', - 'ć' => 'ć', - 'Ĉ' => 'Ĉ', - 'ĉ' => 'ĉ', - 'Ċ' => 'Ċ', - 'ċ' => 'ċ', - 'Č' => 'Č', - 'č' => 'č', - 'Ď' => 'Ď', - 'ď' => 'ď', - 'Ē' => 'Ē', - 'ē' => 'ē', - 'Ĕ' => 'Ĕ', - 'ĕ' => 'ĕ', - 'Ė' => 'Ė', - 'ė' => 'ė', - 'Ę' => 'Ę', - 'ę' => 'ę', - 'Ě' => 'Ě', - 'ě' => 'ě', - 'Ĝ' => 'Ĝ', - 'ĝ' => 'ĝ', - 'Ğ' => 'Ğ', - 'ğ' => 'ğ', - 'Ġ' => 'Ġ', - 'ġ' => 'ġ', - 'Ģ' => 'Ģ', - 'ģ' => 'ģ', - 'Ĥ' => 'Ĥ', - 'ĥ' => 'ĥ', - 'Ĩ' => 'Ĩ', - 'ĩ' => 'ĩ', - 'Ī' => 'Ī', - 'ī' => 'ī', - 'Ĭ' => 'Ĭ', - 'ĭ' => 'ĭ', - 'Į' => 'Į', - 'į' => 'į', - 'İ' => 'İ', - 'Ĵ' => 'Ĵ', - 'ĵ' => 'ĵ', - 'Ķ' => 'Ķ', - 'ķ' => 'ķ', - 'Ĺ' => 'Ĺ', - 'ĺ' => 'ĺ', - 'Ļ' => 'Ļ', - 'ļ' => 'ļ', - 'Ľ' => 'Ľ', - 'ľ' => 'ľ', - 'Ń' => 'Ń', - 'ń' => 'ń', - 'Ņ' => 'Ņ', - 'ņ' => 'ņ', - 'Ň' => 'Ň', - 'ň' => 'ň', - 'Ō' => 'Ō', - 'ō' => 'ō', - 'Ŏ' => 'Ŏ', - 'ŏ' => 'ŏ', - 'Ő' => 'Ő', - 'ő' => 'ő', - 'Ŕ' => 'Ŕ', - 'ŕ' => 'ŕ', - 'Ŗ' => 'Ŗ', - 'ŗ' => 'ŗ', - 'Ř' => 'Ř', - 'ř' => 'ř', - 'Ś' => 'Ś', - 'ś' => 'ś', - 'Ŝ' => 'Ŝ', - 'ŝ' => 'ŝ', - 'Ş' => 'Ş', - 'ş' => 'ş', - 'Š' => 'Š', - 'š' => 'š', - 'Ţ' => 'Ţ', - 'ţ' => 'ţ', - 'Ť' => 'Ť', - 'ť' => 'ť', - 'Ũ' => 'Ũ', - 'ũ' => 'ũ', - 'Ū' => 'Ū', - 'ū' => 'ū', - 'Ŭ' => 'Ŭ', - 'ŭ' => 'ŭ', - 'Ů' => 'Ů', - 'ů' => 'ů', - 'Ű' => 'Ű', - 'ű' => 'ű', - 'Ų' => 'Ų', - 'ų' => 'ų', - 'Ŵ' => 'Ŵ', - 'ŵ' => 'ŵ', - 'Ŷ' => 'Ŷ', - 'ŷ' => 'ŷ', - 'Ÿ' => 'Ÿ', - 'Ź' => 'Ź', - 'ź' => 'ź', - 'Ż' => 'Ż', - 'ż' => 'ż', - 'Ž' => 'Ž', - 'ž' => 'ž', - 'Ơ' => 'Ơ', - 'ơ' => 'ơ', - 'Ư' => 'Ư', - 'ư' => 'ư', - 'Ǎ' => 'Ǎ', - 'ǎ' => 'ǎ', - 'Ǐ' => 'Ǐ', - 'ǐ' => 'ǐ', - 'Ǒ' => 'Ǒ', - 'ǒ' => 'ǒ', - 'Ǔ' => 'Ǔ', - 'ǔ' => 'ǔ', - 'Ǖ' => 'Ǖ', - 'ǖ' => 'ǖ', - 'Ǘ' => 'Ǘ', - 'ǘ' => 'ǘ', - 'Ǚ' => 'Ǚ', - 'ǚ' => 'ǚ', - 'Ǜ' => 'Ǜ', - 'ǜ' => 'ǜ', - 'Ǟ' => 'Ǟ', - 'ǟ' => 'ǟ', - 'Ǡ' => 'Ǡ', - 'ǡ' => 'ǡ', - 'Ǣ' => 'Ǣ', - 'ǣ' => 'ǣ', - 'Ǧ' => 'Ǧ', - 'ǧ' => 'ǧ', - 'Ǩ' => 'Ǩ', - 'ǩ' => 'ǩ', - 'Ǫ' => 'Ǫ', - 'ǫ' => 'ǫ', - 'Ǭ' => 'Ǭ', - 'ǭ' => 'ǭ', - 'Ǯ' => 'Ǯ', - 'ǯ' => 'ǯ', - 'ǰ' => 'ǰ', - 'Ǵ' => 'Ǵ', - 'ǵ' => 'ǵ', - 'Ǹ' => 'Ǹ', - 'ǹ' => 'ǹ', - 'Ǻ' => 'Ǻ', - 'ǻ' => 'ǻ', - 'Ǽ' => 'Ǽ', - 'ǽ' => 'ǽ', - 'Ǿ' => 'Ǿ', - 'ǿ' => 'ǿ', - 'Ȁ' => 'Ȁ', - 'ȁ' => 'ȁ', - 'Ȃ' => 'Ȃ', - 'ȃ' => 'ȃ', - 'Ȅ' => 'Ȅ', - 'ȅ' => 'ȅ', - 'Ȇ' => 'Ȇ', - 'ȇ' => 'ȇ', - 'Ȉ' => 'Ȉ', - 'ȉ' => 'ȉ', - 'Ȋ' => 'Ȋ', - 'ȋ' => 'ȋ', - 'Ȍ' => 'Ȍ', - 'ȍ' => 'ȍ', - 'Ȏ' => 'Ȏ', - 'ȏ' => 'ȏ', - 'Ȑ' => 'Ȑ', - 'ȑ' => 'ȑ', - 'Ȓ' => 'Ȓ', - 'ȓ' => 'ȓ', - 'Ȕ' => 'Ȕ', - 'ȕ' => 'ȕ', - 'Ȗ' => 'Ȗ', - 'ȗ' => 'ȗ', - 'Ș' => 'Ș', - 'ș' => 'ș', - 'Ț' => 'Ț', - 'ț' => 'ț', - 'Ȟ' => 'Ȟ', - 'ȟ' => 'ȟ', - 'Ȧ' => 'Ȧ', - 'ȧ' => 'ȧ', - 'Ȩ' => 'Ȩ', - 'ȩ' => 'ȩ', - 'Ȫ' => 'Ȫ', - 'ȫ' => 'ȫ', - 'Ȭ' => 'Ȭ', - 'ȭ' => 'ȭ', - 'Ȯ' => 'Ȯ', - 'ȯ' => 'ȯ', - 'Ȱ' => 'Ȱ', - 'ȱ' => 'ȱ', - 'Ȳ' => 'Ȳ', - 'ȳ' => 'ȳ', - '΅' => '΅', - 'Ά' => 'Ά', - 'Έ' => 'Έ', - 'Ή' => 'Ή', - 'Ί' => 'Ί', - 'Ό' => 'Ό', - 'Ύ' => 'Ύ', - 'Ώ' => 'Ώ', - 'ΐ' => 'ΐ', - 'Ϊ' => 'Ϊ', - 'Ϋ' => 'Ϋ', - 'ά' => 'ά', - 'έ' => 'έ', - 'ή' => 'ή', - 'ί' => 'ί', - 'ΰ' => 'ΰ', - 'ϊ' => 'ϊ', - 'ϋ' => 'ϋ', - 'ό' => 'ό', - 'ύ' => 'ύ', - 'ώ' => 'ώ', - 'ϓ' => 'ϓ', - 'ϔ' => 'ϔ', - 'Ѐ' => 'Ѐ', - 'Ё' => 'Ё', - 'Ѓ' => 'Ѓ', - 'Ї' => 'Ї', - 'Ќ' => 'Ќ', - 'Ѝ' => 'Ѝ', - 'Ў' => 'Ў', - 'Й' => 'Й', - 'й' => 'й', - 'ѐ' => 'ѐ', - 'ё' => 'ё', - 'ѓ' => 'ѓ', - 'ї' => 'ї', - 'ќ' => 'ќ', - 'ѝ' => 'ѝ', - 'ў' => 'ў', - 'Ѷ' => 'Ѷ', - 'ѷ' => 'ѷ', - 'Ӂ' => 'Ӂ', - 'ӂ' => 'ӂ', - 'Ӑ' => 'Ӑ', - 'ӑ' => 'ӑ', - 'Ӓ' => 'Ӓ', - 'ӓ' => 'ӓ', - 'Ӗ' => 'Ӗ', - 'ӗ' => 'ӗ', - 'Ӛ' => 'Ӛ', - 'ӛ' => 'ӛ', - 'Ӝ' => 'Ӝ', - 'ӝ' => 'ӝ', - 'Ӟ' => 'Ӟ', - 'ӟ' => 'ӟ', - 'Ӣ' => 'Ӣ', - 'ӣ' => 'ӣ', - 'Ӥ' => 'Ӥ', - 'ӥ' => 'ӥ', - 'Ӧ' => 'Ӧ', - 'ӧ' => 'ӧ', - 'Ӫ' => 'Ӫ', - 'ӫ' => 'ӫ', - 'Ӭ' => 'Ӭ', - 'ӭ' => 'ӭ', - 'Ӯ' => 'Ӯ', - 'ӯ' => 'ӯ', - 'Ӱ' => 'Ӱ', - 'ӱ' => 'ӱ', - 'Ӳ' => 'Ӳ', - 'ӳ' => 'ӳ', - 'Ӵ' => 'Ӵ', - 'ӵ' => 'ӵ', - 'Ӹ' => 'Ӹ', - 'ӹ' => 'ӹ', - 'آ' => 'آ', - 'أ' => 'أ', - 'ؤ' => 'ؤ', - 'إ' => 'إ', - 'ئ' => 'ئ', - 'ۀ' => 'ۀ', - 'ۂ' => 'ۂ', - 'ۓ' => 'ۓ', - 'ऩ' => 'ऩ', - 'ऱ' => 'ऱ', - 'ऴ' => 'ऴ', - 'ো' => 'ো', - 'ৌ' => 'ৌ', - 'ୈ' => 'ୈ', - 'ୋ' => 'ୋ', - 'ୌ' => 'ୌ', - 'ஔ' => 'ஔ', - 'ொ' => 'ொ', - 'ோ' => 'ோ', - 'ௌ' => 'ௌ', - 'ై' => 'ై', - 'ೀ' => 'ೀ', - 'ೇ' => 'ೇ', - 'ೈ' => 'ೈ', - 'ೊ' => 'ೊ', - 'ೋ' => 'ೋ', - 'ൊ' => 'ൊ', - 'ോ' => 'ോ', - 'ൌ' => 'ൌ', - 'ේ' => 'ේ', - 'ො' => 'ො', - 'ෝ' => 'ෝ', - 'ෞ' => 'ෞ', - 'ဦ' => 'ဦ', - 'ᬆ' => 'ᬆ', - 'ᬈ' => 'ᬈ', - 'ᬊ' => 'ᬊ', - 'ᬌ' => 'ᬌ', - 'ᬎ' => 'ᬎ', - 'ᬒ' => 'ᬒ', - 'ᬻ' => 'ᬻ', - 'ᬽ' => 'ᬽ', - 'ᭀ' => 'ᭀ', - 'ᭁ' => 'ᭁ', - 'ᭃ' => 'ᭃ', - 'Ḁ' => 'Ḁ', - 'ḁ' => 'ḁ', - 'Ḃ' => 'Ḃ', - 'ḃ' => 'ḃ', - 'Ḅ' => 'Ḅ', - 'ḅ' => 'ḅ', - 'Ḇ' => 'Ḇ', - 'ḇ' => 'ḇ', - 'Ḉ' => 'Ḉ', - 'ḉ' => 'ḉ', - 'Ḋ' => 'Ḋ', - 'ḋ' => 'ḋ', - 'Ḍ' => 'Ḍ', - 'ḍ' => 'ḍ', - 'Ḏ' => 'Ḏ', - 'ḏ' => 'ḏ', - 'Ḑ' => 'Ḑ', - 'ḑ' => 'ḑ', - 'Ḓ' => 'Ḓ', - 'ḓ' => 'ḓ', - 'Ḕ' => 'Ḕ', - 'ḕ' => 'ḕ', - 'Ḗ' => 'Ḗ', - 'ḗ' => 'ḗ', - 'Ḙ' => 'Ḙ', - 'ḙ' => 'ḙ', - 'Ḛ' => 'Ḛ', - 'ḛ' => 'ḛ', - 'Ḝ' => 'Ḝ', - 'ḝ' => 'ḝ', - 'Ḟ' => 'Ḟ', - 'ḟ' => 'ḟ', - 'Ḡ' => 'Ḡ', - 'ḡ' => 'ḡ', - 'Ḣ' => 'Ḣ', - 'ḣ' => 'ḣ', - 'Ḥ' => 'Ḥ', - 'ḥ' => 'ḥ', - 'Ḧ' => 'Ḧ', - 'ḧ' => 'ḧ', - 'Ḩ' => 'Ḩ', - 'ḩ' => 'ḩ', - 'Ḫ' => 'Ḫ', - 'ḫ' => 'ḫ', - 'Ḭ' => 'Ḭ', - 'ḭ' => 'ḭ', - 'Ḯ' => 'Ḯ', - 'ḯ' => 'ḯ', - 'Ḱ' => 'Ḱ', - 'ḱ' => 'ḱ', - 'Ḳ' => 'Ḳ', - 'ḳ' => 'ḳ', - 'Ḵ' => 'Ḵ', - 'ḵ' => 'ḵ', - 'Ḷ' => 'Ḷ', - 'ḷ' => 'ḷ', - 'Ḹ' => 'Ḹ', - 'ḹ' => 'ḹ', - 'Ḻ' => 'Ḻ', - 'ḻ' => 'ḻ', - 'Ḽ' => 'Ḽ', - 'ḽ' => 'ḽ', - 'Ḿ' => 'Ḿ', - 'ḿ' => 'ḿ', - 'Ṁ' => 'Ṁ', - 'ṁ' => 'ṁ', - 'Ṃ' => 'Ṃ', - 'ṃ' => 'ṃ', - 'Ṅ' => 'Ṅ', - 'ṅ' => 'ṅ', - 'Ṇ' => 'Ṇ', - 'ṇ' => 'ṇ', - 'Ṉ' => 'Ṉ', - 'ṉ' => 'ṉ', - 'Ṋ' => 'Ṋ', - 'ṋ' => 'ṋ', - 'Ṍ' => 'Ṍ', - 'ṍ' => 'ṍ', - 'Ṏ' => 'Ṏ', - 'ṏ' => 'ṏ', - 'Ṑ' => 'Ṑ', - 'ṑ' => 'ṑ', - 'Ṓ' => 'Ṓ', - 'ṓ' => 'ṓ', - 'Ṕ' => 'Ṕ', - 'ṕ' => 'ṕ', - 'Ṗ' => 'Ṗ', - 'ṗ' => 'ṗ', - 'Ṙ' => 'Ṙ', - 'ṙ' => 'ṙ', - 'Ṛ' => 'Ṛ', - 'ṛ' => 'ṛ', - 'Ṝ' => 'Ṝ', - 'ṝ' => 'ṝ', - 'Ṟ' => 'Ṟ', - 'ṟ' => 'ṟ', - 'Ṡ' => 'Ṡ', - 'ṡ' => 'ṡ', - 'Ṣ' => 'Ṣ', - 'ṣ' => 'ṣ', - 'Ṥ' => 'Ṥ', - 'ṥ' => 'ṥ', - 'Ṧ' => 'Ṧ', - 'ṧ' => 'ṧ', - 'Ṩ' => 'Ṩ', - 'ṩ' => 'ṩ', - 'Ṫ' => 'Ṫ', - 'ṫ' => 'ṫ', - 'Ṭ' => 'Ṭ', - 'ṭ' => 'ṭ', - 'Ṯ' => 'Ṯ', - 'ṯ' => 'ṯ', - 'Ṱ' => 'Ṱ', - 'ṱ' => 'ṱ', - 'Ṳ' => 'Ṳ', - 'ṳ' => 'ṳ', - 'Ṵ' => 'Ṵ', - 'ṵ' => 'ṵ', - 'Ṷ' => 'Ṷ', - 'ṷ' => 'ṷ', - 'Ṹ' => 'Ṹ', - 'ṹ' => 'ṹ', - 'Ṻ' => 'Ṻ', - 'ṻ' => 'ṻ', - 'Ṽ' => 'Ṽ', - 'ṽ' => 'ṽ', - 'Ṿ' => 'Ṿ', - 'ṿ' => 'ṿ', - 'Ẁ' => 'Ẁ', - 'ẁ' => 'ẁ', - 'Ẃ' => 'Ẃ', - 'ẃ' => 'ẃ', - 'Ẅ' => 'Ẅ', - 'ẅ' => 'ẅ', - 'Ẇ' => 'Ẇ', - 'ẇ' => 'ẇ', - 'Ẉ' => 'Ẉ', - 'ẉ' => 'ẉ', - 'Ẋ' => 'Ẋ', - 'ẋ' => 'ẋ', - 'Ẍ' => 'Ẍ', - 'ẍ' => 'ẍ', - 'Ẏ' => 'Ẏ', - 'ẏ' => 'ẏ', - 'Ẑ' => 'Ẑ', - 'ẑ' => 'ẑ', - 'Ẓ' => 'Ẓ', - 'ẓ' => 'ẓ', - 'Ẕ' => 'Ẕ', - 'ẕ' => 'ẕ', - 'ẖ' => 'ẖ', - 'ẗ' => 'ẗ', - 'ẘ' => 'ẘ', - 'ẙ' => 'ẙ', - 'ẛ' => 'ẛ', - 'Ạ' => 'Ạ', - 'ạ' => 'ạ', - 'Ả' => 'Ả', - 'ả' => 'ả', - 'Ấ' => 'Ấ', - 'ấ' => 'ấ', - 'Ầ' => 'Ầ', - 'ầ' => 'ầ', - 'Ẩ' => 'Ẩ', - 'ẩ' => 'ẩ', - 'Ẫ' => 'Ẫ', - 'ẫ' => 'ẫ', - 'Ậ' => 'Ậ', - 'ậ' => 'ậ', - 'Ắ' => 'Ắ', - 'ắ' => 'ắ', - 'Ằ' => 'Ằ', - 'ằ' => 'ằ', - 'Ẳ' => 'Ẳ', - 'ẳ' => 'ẳ', - 'Ẵ' => 'Ẵ', - 'ẵ' => 'ẵ', - 'Ặ' => 'Ặ', - 'ặ' => 'ặ', - 'Ẹ' => 'Ẹ', - 'ẹ' => 'ẹ', - 'Ẻ' => 'Ẻ', - 'ẻ' => 'ẻ', - 'Ẽ' => 'Ẽ', - 'ẽ' => 'ẽ', - 'Ế' => 'Ế', - 'ế' => 'ế', - 'Ề' => 'Ề', - 'ề' => 'ề', - 'Ể' => 'Ể', - 'ể' => 'ể', - 'Ễ' => 'Ễ', - 'ễ' => 'ễ', - 'Ệ' => 'Ệ', - 'ệ' => 'ệ', - 'Ỉ' => 'Ỉ', - 'ỉ' => 'ỉ', - 'Ị' => 'Ị', - 'ị' => 'ị', - 'Ọ' => 'Ọ', - 'ọ' => 'ọ', - 'Ỏ' => 'Ỏ', - 'ỏ' => 'ỏ', - 'Ố' => 'Ố', - 'ố' => 'ố', - 'Ồ' => 'Ồ', - 'ồ' => 'ồ', - 'Ổ' => 'Ổ', - 'ổ' => 'ổ', - 'Ỗ' => 'Ỗ', - 'ỗ' => 'ỗ', - 'Ộ' => 'Ộ', - 'ộ' => 'ộ', - 'Ớ' => 'Ớ', - 'ớ' => 'ớ', - 'Ờ' => 'Ờ', - 'ờ' => 'ờ', - 'Ở' => 'Ở', - 'ở' => 'ở', - 'Ỡ' => 'Ỡ', - 'ỡ' => 'ỡ', - 'Ợ' => 'Ợ', - 'ợ' => 'ợ', - 'Ụ' => 'Ụ', - 'ụ' => 'ụ', - 'Ủ' => 'Ủ', - 'ủ' => 'ủ', - 'Ứ' => 'Ứ', - 'ứ' => 'ứ', - 'Ừ' => 'Ừ', - 'ừ' => 'ừ', - 'Ử' => 'Ử', - 'ử' => 'ử', - 'Ữ' => 'Ữ', - 'ữ' => 'ữ', - 'Ự' => 'Ự', - 'ự' => 'ự', - 'Ỳ' => 'Ỳ', - 'ỳ' => 'ỳ', - 'Ỵ' => 'Ỵ', - 'ỵ' => 'ỵ', - 'Ỷ' => 'Ỷ', - 'ỷ' => 'ỷ', - 'Ỹ' => 'Ỹ', - 'ỹ' => 'ỹ', - 'ἀ' => 'ἀ', - 'ἁ' => 'ἁ', - 'ἂ' => 'ἂ', - 'ἃ' => 'ἃ', - 'ἄ' => 'ἄ', - 'ἅ' => 'ἅ', - 'ἆ' => 'ἆ', - 'ἇ' => 'ἇ', - 'Ἀ' => 'Ἀ', - 'Ἁ' => 'Ἁ', - 'Ἂ' => 'Ἂ', - 'Ἃ' => 'Ἃ', - 'Ἄ' => 'Ἄ', - 'Ἅ' => 'Ἅ', - 'Ἆ' => 'Ἆ', - 'Ἇ' => 'Ἇ', - 'ἐ' => 'ἐ', - 'ἑ' => 'ἑ', - 'ἒ' => 'ἒ', - 'ἓ' => 'ἓ', - 'ἔ' => 'ἔ', - 'ἕ' => 'ἕ', - 'Ἐ' => 'Ἐ', - 'Ἑ' => 'Ἑ', - 'Ἒ' => 'Ἒ', - 'Ἓ' => 'Ἓ', - 'Ἔ' => 'Ἔ', - 'Ἕ' => 'Ἕ', - 'ἠ' => 'ἠ', - 'ἡ' => 'ἡ', - 'ἢ' => 'ἢ', - 'ἣ' => 'ἣ', - 'ἤ' => 'ἤ', - 'ἥ' => 'ἥ', - 'ἦ' => 'ἦ', - 'ἧ' => 'ἧ', - 'Ἠ' => 'Ἠ', - 'Ἡ' => 'Ἡ', - 'Ἢ' => 'Ἢ', - 'Ἣ' => 'Ἣ', - 'Ἤ' => 'Ἤ', - 'Ἥ' => 'Ἥ', - 'Ἦ' => 'Ἦ', - 'Ἧ' => 'Ἧ', - 'ἰ' => 'ἰ', - 'ἱ' => 'ἱ', - 'ἲ' => 'ἲ', - 'ἳ' => 'ἳ', - 'ἴ' => 'ἴ', - 'ἵ' => 'ἵ', - 'ἶ' => 'ἶ', - 'ἷ' => 'ἷ', - 'Ἰ' => 'Ἰ', - 'Ἱ' => 'Ἱ', - 'Ἲ' => 'Ἲ', - 'Ἳ' => 'Ἳ', - 'Ἴ' => 'Ἴ', - 'Ἵ' => 'Ἵ', - 'Ἶ' => 'Ἶ', - 'Ἷ' => 'Ἷ', - 'ὀ' => 'ὀ', - 'ὁ' => 'ὁ', - 'ὂ' => 'ὂ', - 'ὃ' => 'ὃ', - 'ὄ' => 'ὄ', - 'ὅ' => 'ὅ', - 'Ὀ' => 'Ὀ', - 'Ὁ' => 'Ὁ', - 'Ὂ' => 'Ὂ', - 'Ὃ' => 'Ὃ', - 'Ὄ' => 'Ὄ', - 'Ὅ' => 'Ὅ', - 'ὐ' => 'ὐ', - 'ὑ' => 'ὑ', - 'ὒ' => 'ὒ', - 'ὓ' => 'ὓ', - 'ὔ' => 'ὔ', - 'ὕ' => 'ὕ', - 'ὖ' => 'ὖ', - 'ὗ' => 'ὗ', - 'Ὑ' => 'Ὑ', - 'Ὓ' => 'Ὓ', - 'Ὕ' => 'Ὕ', - 'Ὗ' => 'Ὗ', - 'ὠ' => 'ὠ', - 'ὡ' => 'ὡ', - 'ὢ' => 'ὢ', - 'ὣ' => 'ὣ', - 'ὤ' => 'ὤ', - 'ὥ' => 'ὥ', - 'ὦ' => 'ὦ', - 'ὧ' => 'ὧ', - 'Ὠ' => 'Ὠ', - 'Ὡ' => 'Ὡ', - 'Ὢ' => 'Ὢ', - 'Ὣ' => 'Ὣ', - 'Ὤ' => 'Ὤ', - 'Ὥ' => 'Ὥ', - 'Ὦ' => 'Ὦ', - 'Ὧ' => 'Ὧ', - 'ὰ' => 'ὰ', - 'ὲ' => 'ὲ', - 'ὴ' => 'ὴ', - 'ὶ' => 'ὶ', - 'ὸ' => 'ὸ', - 'ὺ' => 'ὺ', - 'ὼ' => 'ὼ', - 'ᾀ' => 'ᾀ', - 'ᾁ' => 'ᾁ', - 'ᾂ' => 'ᾂ', - 'ᾃ' => 'ᾃ', - 'ᾄ' => 'ᾄ', - 'ᾅ' => 'ᾅ', - 'ᾆ' => 'ᾆ', - 'ᾇ' => 'ᾇ', - 'ᾈ' => 'ᾈ', - 'ᾉ' => 'ᾉ', - 'ᾊ' => 'ᾊ', - 'ᾋ' => 'ᾋ', - 'ᾌ' => 'ᾌ', - 'ᾍ' => 'ᾍ', - 'ᾎ' => 'ᾎ', - 'ᾏ' => 'ᾏ', - 'ᾐ' => 'ᾐ', - 'ᾑ' => 'ᾑ', - 'ᾒ' => 'ᾒ', - 'ᾓ' => 'ᾓ', - 'ᾔ' => 'ᾔ', - 'ᾕ' => 'ᾕ', - 'ᾖ' => 'ᾖ', - 'ᾗ' => 'ᾗ', - 'ᾘ' => 'ᾘ', - 'ᾙ' => 'ᾙ', - 'ᾚ' => 'ᾚ', - 'ᾛ' => 'ᾛ', - 'ᾜ' => 'ᾜ', - 'ᾝ' => 'ᾝ', - 'ᾞ' => 'ᾞ', - 'ᾟ' => 'ᾟ', - 'ᾠ' => 'ᾠ', - 'ᾡ' => 'ᾡ', - 'ᾢ' => 'ᾢ', - 'ᾣ' => 'ᾣ', - 'ᾤ' => 'ᾤ', - 'ᾥ' => 'ᾥ', - 'ᾦ' => 'ᾦ', - 'ᾧ' => 'ᾧ', - 'ᾨ' => 'ᾨ', - 'ᾩ' => 'ᾩ', - 'ᾪ' => 'ᾪ', - 'ᾫ' => 'ᾫ', - 'ᾬ' => 'ᾬ', - 'ᾭ' => 'ᾭ', - 'ᾮ' => 'ᾮ', - 'ᾯ' => 'ᾯ', - 'ᾰ' => 'ᾰ', - 'ᾱ' => 'ᾱ', - 'ᾲ' => 'ᾲ', - 'ᾳ' => 'ᾳ', - 'ᾴ' => 'ᾴ', - 'ᾶ' => 'ᾶ', - 'ᾷ' => 'ᾷ', - 'Ᾰ' => 'Ᾰ', - 'Ᾱ' => 'Ᾱ', - 'Ὰ' => 'Ὰ', - 'ᾼ' => 'ᾼ', - '῁' => '῁', - 'ῂ' => 'ῂ', - 'ῃ' => 'ῃ', - 'ῄ' => 'ῄ', - 'ῆ' => 'ῆ', - 'ῇ' => 'ῇ', - 'Ὲ' => 'Ὲ', - 'Ὴ' => 'Ὴ', - 'ῌ' => 'ῌ', - '῍' => '῍', - '῎' => '῎', - '῏' => '῏', - 'ῐ' => 'ῐ', - 'ῑ' => 'ῑ', - 'ῒ' => 'ῒ', - 'ῖ' => 'ῖ', - 'ῗ' => 'ῗ', - 'Ῐ' => 'Ῐ', - 'Ῑ' => 'Ῑ', - 'Ὶ' => 'Ὶ', - '῝' => '῝', - '῞' => '῞', - '῟' => '῟', - 'ῠ' => 'ῠ', - 'ῡ' => 'ῡ', - 'ῢ' => 'ῢ', - 'ῤ' => 'ῤ', - 'ῥ' => 'ῥ', - 'ῦ' => 'ῦ', - 'ῧ' => 'ῧ', - 'Ῠ' => 'Ῠ', - 'Ῡ' => 'Ῡ', - 'Ὺ' => 'Ὺ', - 'Ῥ' => 'Ῥ', - '῭' => '῭', - 'ῲ' => 'ῲ', - 'ῳ' => 'ῳ', - 'ῴ' => 'ῴ', - 'ῶ' => 'ῶ', - 'ῷ' => 'ῷ', - 'Ὸ' => 'Ὸ', - 'Ὼ' => 'Ὼ', - 'ῼ' => 'ῼ', - '↚' => '↚', - '↛' => '↛', - '↮' => '↮', - '⇍' => '⇍', - '⇎' => '⇎', - '⇏' => '⇏', - '∄' => '∄', - '∉' => '∉', - '∌' => '∌', - '∤' => '∤', - '∦' => '∦', - '≁' => '≁', - '≄' => '≄', - '≇' => '≇', - '≉' => '≉', - '≠' => '≠', - '≢' => '≢', - '≭' => '≭', - '≮' => '≮', - '≯' => '≯', - '≰' => '≰', - '≱' => '≱', - '≴' => '≴', - '≵' => '≵', - '≸' => '≸', - '≹' => '≹', - '⊀' => '⊀', - '⊁' => '⊁', - '⊄' => '⊄', - '⊅' => '⊅', - '⊈' => '⊈', - '⊉' => '⊉', - '⊬' => '⊬', - '⊭' => '⊭', - '⊮' => '⊮', - '⊯' => '⊯', - '⋠' => '⋠', - '⋡' => '⋡', - '⋢' => '⋢', - '⋣' => '⋣', - '⋪' => '⋪', - '⋫' => '⋫', - '⋬' => '⋬', - '⋭' => '⋭', - 'が' => 'が', - 'ぎ' => 'ぎ', - 'ぐ' => 'ぐ', - 'げ' => 'げ', - 'ご' => 'ご', - 'ざ' => 'ざ', - 'じ' => 'じ', - 'ず' => 'ず', - 'ぜ' => 'ぜ', - 'ぞ' => 'ぞ', - 'だ' => 'だ', - 'ぢ' => 'ぢ', - 'づ' => 'づ', - 'で' => 'で', - 'ど' => 'ど', - 'ば' => 'ば', - 'ぱ' => 'ぱ', - 'び' => 'び', - 'ぴ' => 'ぴ', - 'ぶ' => 'ぶ', - 'ぷ' => 'ぷ', - 'べ' => 'べ', - 'ぺ' => 'ぺ', - 'ぼ' => 'ぼ', - 'ぽ' => 'ぽ', - 'ゔ' => 'ゔ', - 'ゞ' => 'ゞ', - 'ガ' => 'ガ', - 'ギ' => 'ギ', - 'グ' => 'グ', - 'ゲ' => 'ゲ', - 'ゴ' => 'ゴ', - 'ザ' => 'ザ', - 'ジ' => 'ジ', - 'ズ' => 'ズ', - 'ゼ' => 'ゼ', - 'ゾ' => 'ゾ', - 'ダ' => 'ダ', - 'ヂ' => 'ヂ', - 'ヅ' => 'ヅ', - 'デ' => 'デ', - 'ド' => 'ド', - 'バ' => 'バ', - 'パ' => 'パ', - 'ビ' => 'ビ', - 'ピ' => 'ピ', - 'ブ' => 'ブ', - 'プ' => 'プ', - 'ベ' => 'ベ', - 'ペ' => 'ペ', - 'ボ' => 'ボ', - 'ポ' => 'ポ', - 'ヴ' => 'ヴ', - 'ヷ' => 'ヷ', - 'ヸ' => 'ヸ', - 'ヹ' => 'ヹ', - 'ヺ' => 'ヺ', - 'ヾ' => 'ヾ', - '𑂚' => '𑂚', - '𑂜' => '𑂜', - '𑂫' => '𑂫', - '𑄮' => '𑄮', - '𑄯' => '𑄯', - '𑍋' => '𑍋', - '𑍌' => '𑍌', - '𑒻' => '𑒻', - '𑒼' => '𑒼', - '𑒾' => '𑒾', - '𑖺' => '𑖺', - '𑖻' => '𑖻', - '𑤸' => '𑤸', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php deleted file mode 100644 index 5a3e8e096..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php +++ /dev/null @@ -1,2065 +0,0 @@ - 'À', - 'Á' => 'Á', - 'Â' => 'Â', - 'Ã' => 'Ã', - 'Ä' => 'Ä', - 'Å' => 'Å', - 'Ç' => 'Ç', - 'È' => 'È', - 'É' => 'É', - 'Ê' => 'Ê', - 'Ë' => 'Ë', - 'Ì' => 'Ì', - 'Í' => 'Í', - 'Î' => 'Î', - 'Ï' => 'Ï', - 'Ñ' => 'Ñ', - 'Ò' => 'Ò', - 'Ó' => 'Ó', - 'Ô' => 'Ô', - 'Õ' => 'Õ', - 'Ö' => 'Ö', - 'Ù' => 'Ù', - 'Ú' => 'Ú', - 'Û' => 'Û', - 'Ü' => 'Ü', - 'Ý' => 'Ý', - 'à' => 'à', - 'á' => 'á', - 'â' => 'â', - 'ã' => 'ã', - 'ä' => 'ä', - 'å' => 'å', - 'ç' => 'ç', - 'è' => 'è', - 'é' => 'é', - 'ê' => 'ê', - 'ë' => 'ë', - 'ì' => 'ì', - 'í' => 'í', - 'î' => 'î', - 'ï' => 'ï', - 'ñ' => 'ñ', - 'ò' => 'ò', - 'ó' => 'ó', - 'ô' => 'ô', - 'õ' => 'õ', - 'ö' => 'ö', - 'ù' => 'ù', - 'ú' => 'ú', - 'û' => 'û', - 'ü' => 'ü', - 'ý' => 'ý', - 'ÿ' => 'ÿ', - 'Ā' => 'Ā', - 'ā' => 'ā', - 'Ă' => 'Ă', - 'ă' => 'ă', - 'Ą' => 'Ą', - 'ą' => 'ą', - 'Ć' => 'Ć', - 'ć' => 'ć', - 'Ĉ' => 'Ĉ', - 'ĉ' => 'ĉ', - 'Ċ' => 'Ċ', - 'ċ' => 'ċ', - 'Č' => 'Č', - 'č' => 'č', - 'Ď' => 'Ď', - 'ď' => 'ď', - 'Ē' => 'Ē', - 'ē' => 'ē', - 'Ĕ' => 'Ĕ', - 'ĕ' => 'ĕ', - 'Ė' => 'Ė', - 'ė' => 'ė', - 'Ę' => 'Ę', - 'ę' => 'ę', - 'Ě' => 'Ě', - 'ě' => 'ě', - 'Ĝ' => 'Ĝ', - 'ĝ' => 'ĝ', - 'Ğ' => 'Ğ', - 'ğ' => 'ğ', - 'Ġ' => 'Ġ', - 'ġ' => 'ġ', - 'Ģ' => 'Ģ', - 'ģ' => 'ģ', - 'Ĥ' => 'Ĥ', - 'ĥ' => 'ĥ', - 'Ĩ' => 'Ĩ', - 'ĩ' => 'ĩ', - 'Ī' => 'Ī', - 'ī' => 'ī', - 'Ĭ' => 'Ĭ', - 'ĭ' => 'ĭ', - 'Į' => 'Į', - 'į' => 'į', - 'İ' => 'İ', - 'Ĵ' => 'Ĵ', - 'ĵ' => 'ĵ', - 'Ķ' => 'Ķ', - 'ķ' => 'ķ', - 'Ĺ' => 'Ĺ', - 'ĺ' => 'ĺ', - 'Ļ' => 'Ļ', - 'ļ' => 'ļ', - 'Ľ' => 'Ľ', - 'ľ' => 'ľ', - 'Ń' => 'Ń', - 'ń' => 'ń', - 'Ņ' => 'Ņ', - 'ņ' => 'ņ', - 'Ň' => 'Ň', - 'ň' => 'ň', - 'Ō' => 'Ō', - 'ō' => 'ō', - 'Ŏ' => 'Ŏ', - 'ŏ' => 'ŏ', - 'Ő' => 'Ő', - 'ő' => 'ő', - 'Ŕ' => 'Ŕ', - 'ŕ' => 'ŕ', - 'Ŗ' => 'Ŗ', - 'ŗ' => 'ŗ', - 'Ř' => 'Ř', - 'ř' => 'ř', - 'Ś' => 'Ś', - 'ś' => 'ś', - 'Ŝ' => 'Ŝ', - 'ŝ' => 'ŝ', - 'Ş' => 'Ş', - 'ş' => 'ş', - 'Š' => 'Š', - 'š' => 'š', - 'Ţ' => 'Ţ', - 'ţ' => 'ţ', - 'Ť' => 'Ť', - 'ť' => 'ť', - 'Ũ' => 'Ũ', - 'ũ' => 'ũ', - 'Ū' => 'Ū', - 'ū' => 'ū', - 'Ŭ' => 'Ŭ', - 'ŭ' => 'ŭ', - 'Ů' => 'Ů', - 'ů' => 'ů', - 'Ű' => 'Ű', - 'ű' => 'ű', - 'Ų' => 'Ų', - 'ų' => 'ų', - 'Ŵ' => 'Ŵ', - 'ŵ' => 'ŵ', - 'Ŷ' => 'Ŷ', - 'ŷ' => 'ŷ', - 'Ÿ' => 'Ÿ', - 'Ź' => 'Ź', - 'ź' => 'ź', - 'Ż' => 'Ż', - 'ż' => 'ż', - 'Ž' => 'Ž', - 'ž' => 'ž', - 'Ơ' => 'Ơ', - 'ơ' => 'ơ', - 'Ư' => 'Ư', - 'ư' => 'ư', - 'Ǎ' => 'Ǎ', - 'ǎ' => 'ǎ', - 'Ǐ' => 'Ǐ', - 'ǐ' => 'ǐ', - 'Ǒ' => 'Ǒ', - 'ǒ' => 'ǒ', - 'Ǔ' => 'Ǔ', - 'ǔ' => 'ǔ', - 'Ǖ' => 'Ǖ', - 'ǖ' => 'ǖ', - 'Ǘ' => 'Ǘ', - 'ǘ' => 'ǘ', - 'Ǚ' => 'Ǚ', - 'ǚ' => 'ǚ', - 'Ǜ' => 'Ǜ', - 'ǜ' => 'ǜ', - 'Ǟ' => 'Ǟ', - 'ǟ' => 'ǟ', - 'Ǡ' => 'Ǡ', - 'ǡ' => 'ǡ', - 'Ǣ' => 'Ǣ', - 'ǣ' => 'ǣ', - 'Ǧ' => 'Ǧ', - 'ǧ' => 'ǧ', - 'Ǩ' => 'Ǩ', - 'ǩ' => 'ǩ', - 'Ǫ' => 'Ǫ', - 'ǫ' => 'ǫ', - 'Ǭ' => 'Ǭ', - 'ǭ' => 'ǭ', - 'Ǯ' => 'Ǯ', - 'ǯ' => 'ǯ', - 'ǰ' => 'ǰ', - 'Ǵ' => 'Ǵ', - 'ǵ' => 'ǵ', - 'Ǹ' => 'Ǹ', - 'ǹ' => 'ǹ', - 'Ǻ' => 'Ǻ', - 'ǻ' => 'ǻ', - 'Ǽ' => 'Ǽ', - 'ǽ' => 'ǽ', - 'Ǿ' => 'Ǿ', - 'ǿ' => 'ǿ', - 'Ȁ' => 'Ȁ', - 'ȁ' => 'ȁ', - 'Ȃ' => 'Ȃ', - 'ȃ' => 'ȃ', - 'Ȅ' => 'Ȅ', - 'ȅ' => 'ȅ', - 'Ȇ' => 'Ȇ', - 'ȇ' => 'ȇ', - 'Ȉ' => 'Ȉ', - 'ȉ' => 'ȉ', - 'Ȋ' => 'Ȋ', - 'ȋ' => 'ȋ', - 'Ȍ' => 'Ȍ', - 'ȍ' => 'ȍ', - 'Ȏ' => 'Ȏ', - 'ȏ' => 'ȏ', - 'Ȑ' => 'Ȑ', - 'ȑ' => 'ȑ', - 'Ȓ' => 'Ȓ', - 'ȓ' => 'ȓ', - 'Ȕ' => 'Ȕ', - 'ȕ' => 'ȕ', - 'Ȗ' => 'Ȗ', - 'ȗ' => 'ȗ', - 'Ș' => 'Ș', - 'ș' => 'ș', - 'Ț' => 'Ț', - 'ț' => 'ț', - 'Ȟ' => 'Ȟ', - 'ȟ' => 'ȟ', - 'Ȧ' => 'Ȧ', - 'ȧ' => 'ȧ', - 'Ȩ' => 'Ȩ', - 'ȩ' => 'ȩ', - 'Ȫ' => 'Ȫ', - 'ȫ' => 'ȫ', - 'Ȭ' => 'Ȭ', - 'ȭ' => 'ȭ', - 'Ȯ' => 'Ȯ', - 'ȯ' => 'ȯ', - 'Ȱ' => 'Ȱ', - 'ȱ' => 'ȱ', - 'Ȳ' => 'Ȳ', - 'ȳ' => 'ȳ', - '̀' => '̀', - '́' => '́', - '̓' => '̓', - '̈́' => '̈́', - 'ʹ' => 'ʹ', - ';' => ';', - '΅' => '΅', - 'Ά' => 'Ά', - '·' => '·', - 'Έ' => 'Έ', - 'Ή' => 'Ή', - 'Ί' => 'Ί', - 'Ό' => 'Ό', - 'Ύ' => 'Ύ', - 'Ώ' => 'Ώ', - 'ΐ' => 'ΐ', - 'Ϊ' => 'Ϊ', - 'Ϋ' => 'Ϋ', - 'ά' => 'ά', - 'έ' => 'έ', - 'ή' => 'ή', - 'ί' => 'ί', - 'ΰ' => 'ΰ', - 'ϊ' => 'ϊ', - 'ϋ' => 'ϋ', - 'ό' => 'ό', - 'ύ' => 'ύ', - 'ώ' => 'ώ', - 'ϓ' => 'ϓ', - 'ϔ' => 'ϔ', - 'Ѐ' => 'Ѐ', - 'Ё' => 'Ё', - 'Ѓ' => 'Ѓ', - 'Ї' => 'Ї', - 'Ќ' => 'Ќ', - 'Ѝ' => 'Ѝ', - 'Ў' => 'Ў', - 'Й' => 'Й', - 'й' => 'й', - 'ѐ' => 'ѐ', - 'ё' => 'ё', - 'ѓ' => 'ѓ', - 'ї' => 'ї', - 'ќ' => 'ќ', - 'ѝ' => 'ѝ', - 'ў' => 'ў', - 'Ѷ' => 'Ѷ', - 'ѷ' => 'ѷ', - 'Ӂ' => 'Ӂ', - 'ӂ' => 'ӂ', - 'Ӑ' => 'Ӑ', - 'ӑ' => 'ӑ', - 'Ӓ' => 'Ӓ', - 'ӓ' => 'ӓ', - 'Ӗ' => 'Ӗ', - 'ӗ' => 'ӗ', - 'Ӛ' => 'Ӛ', - 'ӛ' => 'ӛ', - 'Ӝ' => 'Ӝ', - 'ӝ' => 'ӝ', - 'Ӟ' => 'Ӟ', - 'ӟ' => 'ӟ', - 'Ӣ' => 'Ӣ', - 'ӣ' => 'ӣ', - 'Ӥ' => 'Ӥ', - 'ӥ' => 'ӥ', - 'Ӧ' => 'Ӧ', - 'ӧ' => 'ӧ', - 'Ӫ' => 'Ӫ', - 'ӫ' => 'ӫ', - 'Ӭ' => 'Ӭ', - 'ӭ' => 'ӭ', - 'Ӯ' => 'Ӯ', - 'ӯ' => 'ӯ', - 'Ӱ' => 'Ӱ', - 'ӱ' => 'ӱ', - 'Ӳ' => 'Ӳ', - 'ӳ' => 'ӳ', - 'Ӵ' => 'Ӵ', - 'ӵ' => 'ӵ', - 'Ӹ' => 'Ӹ', - 'ӹ' => 'ӹ', - 'آ' => 'آ', - 'أ' => 'أ', - 'ؤ' => 'ؤ', - 'إ' => 'إ', - 'ئ' => 'ئ', - 'ۀ' => 'ۀ', - 'ۂ' => 'ۂ', - 'ۓ' => 'ۓ', - 'ऩ' => 'ऩ', - 'ऱ' => 'ऱ', - 'ऴ' => 'ऴ', - 'क़' => 'क़', - 'ख़' => 'ख़', - 'ग़' => 'ग़', - 'ज़' => 'ज़', - 'ड़' => 'ड़', - 'ढ़' => 'ढ़', - 'फ़' => 'फ़', - 'य़' => 'य़', - 'ো' => 'ো', - 'ৌ' => 'ৌ', - 'ড়' => 'ড়', - 'ঢ়' => 'ঢ়', - 'য়' => 'য়', - 'ਲ਼' => 'ਲ਼', - 'ਸ਼' => 'ਸ਼', - 'ਖ਼' => 'ਖ਼', - 'ਗ਼' => 'ਗ਼', - 'ਜ਼' => 'ਜ਼', - 'ਫ਼' => 'ਫ਼', - 'ୈ' => 'ୈ', - 'ୋ' => 'ୋ', - 'ୌ' => 'ୌ', - 'ଡ଼' => 'ଡ଼', - 'ଢ଼' => 'ଢ଼', - 'ஔ' => 'ஔ', - 'ொ' => 'ொ', - 'ோ' => 'ோ', - 'ௌ' => 'ௌ', - 'ై' => 'ై', - 'ೀ' => 'ೀ', - 'ೇ' => 'ೇ', - 'ೈ' => 'ೈ', - 'ೊ' => 'ೊ', - 'ೋ' => 'ೋ', - 'ൊ' => 'ൊ', - 'ോ' => 'ോ', - 'ൌ' => 'ൌ', - 'ේ' => 'ේ', - 'ො' => 'ො', - 'ෝ' => 'ෝ', - 'ෞ' => 'ෞ', - 'གྷ' => 'གྷ', - 'ཌྷ' => 'ཌྷ', - 'དྷ' => 'དྷ', - 'བྷ' => 'བྷ', - 'ཛྷ' => 'ཛྷ', - 'ཀྵ' => 'ཀྵ', - 'ཱི' => 'ཱི', - 'ཱུ' => 'ཱུ', - 'ྲྀ' => 'ྲྀ', - 'ླྀ' => 'ླྀ', - 'ཱྀ' => 'ཱྀ', - 'ྒྷ' => 'ྒྷ', - 'ྜྷ' => 'ྜྷ', - 'ྡྷ' => 'ྡྷ', - 'ྦྷ' => 'ྦྷ', - 'ྫྷ' => 'ྫྷ', - 'ྐྵ' => 'ྐྵ', - 'ဦ' => 'ဦ', - 'ᬆ' => 'ᬆ', - 'ᬈ' => 'ᬈ', - 'ᬊ' => 'ᬊ', - 'ᬌ' => 'ᬌ', - 'ᬎ' => 'ᬎ', - 'ᬒ' => 'ᬒ', - 'ᬻ' => 'ᬻ', - 'ᬽ' => 'ᬽ', - 'ᭀ' => 'ᭀ', - 'ᭁ' => 'ᭁ', - 'ᭃ' => 'ᭃ', - 'Ḁ' => 'Ḁ', - 'ḁ' => 'ḁ', - 'Ḃ' => 'Ḃ', - 'ḃ' => 'ḃ', - 'Ḅ' => 'Ḅ', - 'ḅ' => 'ḅ', - 'Ḇ' => 'Ḇ', - 'ḇ' => 'ḇ', - 'Ḉ' => 'Ḉ', - 'ḉ' => 'ḉ', - 'Ḋ' => 'Ḋ', - 'ḋ' => 'ḋ', - 'Ḍ' => 'Ḍ', - 'ḍ' => 'ḍ', - 'Ḏ' => 'Ḏ', - 'ḏ' => 'ḏ', - 'Ḑ' => 'Ḑ', - 'ḑ' => 'ḑ', - 'Ḓ' => 'Ḓ', - 'ḓ' => 'ḓ', - 'Ḕ' => 'Ḕ', - 'ḕ' => 'ḕ', - 'Ḗ' => 'Ḗ', - 'ḗ' => 'ḗ', - 'Ḙ' => 'Ḙ', - 'ḙ' => 'ḙ', - 'Ḛ' => 'Ḛ', - 'ḛ' => 'ḛ', - 'Ḝ' => 'Ḝ', - 'ḝ' => 'ḝ', - 'Ḟ' => 'Ḟ', - 'ḟ' => 'ḟ', - 'Ḡ' => 'Ḡ', - 'ḡ' => 'ḡ', - 'Ḣ' => 'Ḣ', - 'ḣ' => 'ḣ', - 'Ḥ' => 'Ḥ', - 'ḥ' => 'ḥ', - 'Ḧ' => 'Ḧ', - 'ḧ' => 'ḧ', - 'Ḩ' => 'Ḩ', - 'ḩ' => 'ḩ', - 'Ḫ' => 'Ḫ', - 'ḫ' => 'ḫ', - 'Ḭ' => 'Ḭ', - 'ḭ' => 'ḭ', - 'Ḯ' => 'Ḯ', - 'ḯ' => 'ḯ', - 'Ḱ' => 'Ḱ', - 'ḱ' => 'ḱ', - 'Ḳ' => 'Ḳ', - 'ḳ' => 'ḳ', - 'Ḵ' => 'Ḵ', - 'ḵ' => 'ḵ', - 'Ḷ' => 'Ḷ', - 'ḷ' => 'ḷ', - 'Ḹ' => 'Ḹ', - 'ḹ' => 'ḹ', - 'Ḻ' => 'Ḻ', - 'ḻ' => 'ḻ', - 'Ḽ' => 'Ḽ', - 'ḽ' => 'ḽ', - 'Ḿ' => 'Ḿ', - 'ḿ' => 'ḿ', - 'Ṁ' => 'Ṁ', - 'ṁ' => 'ṁ', - 'Ṃ' => 'Ṃ', - 'ṃ' => 'ṃ', - 'Ṅ' => 'Ṅ', - 'ṅ' => 'ṅ', - 'Ṇ' => 'Ṇ', - 'ṇ' => 'ṇ', - 'Ṉ' => 'Ṉ', - 'ṉ' => 'ṉ', - 'Ṋ' => 'Ṋ', - 'ṋ' => 'ṋ', - 'Ṍ' => 'Ṍ', - 'ṍ' => 'ṍ', - 'Ṏ' => 'Ṏ', - 'ṏ' => 'ṏ', - 'Ṑ' => 'Ṑ', - 'ṑ' => 'ṑ', - 'Ṓ' => 'Ṓ', - 'ṓ' => 'ṓ', - 'Ṕ' => 'Ṕ', - 'ṕ' => 'ṕ', - 'Ṗ' => 'Ṗ', - 'ṗ' => 'ṗ', - 'Ṙ' => 'Ṙ', - 'ṙ' => 'ṙ', - 'Ṛ' => 'Ṛ', - 'ṛ' => 'ṛ', - 'Ṝ' => 'Ṝ', - 'ṝ' => 'ṝ', - 'Ṟ' => 'Ṟ', - 'ṟ' => 'ṟ', - 'Ṡ' => 'Ṡ', - 'ṡ' => 'ṡ', - 'Ṣ' => 'Ṣ', - 'ṣ' => 'ṣ', - 'Ṥ' => 'Ṥ', - 'ṥ' => 'ṥ', - 'Ṧ' => 'Ṧ', - 'ṧ' => 'ṧ', - 'Ṩ' => 'Ṩ', - 'ṩ' => 'ṩ', - 'Ṫ' => 'Ṫ', - 'ṫ' => 'ṫ', - 'Ṭ' => 'Ṭ', - 'ṭ' => 'ṭ', - 'Ṯ' => 'Ṯ', - 'ṯ' => 'ṯ', - 'Ṱ' => 'Ṱ', - 'ṱ' => 'ṱ', - 'Ṳ' => 'Ṳ', - 'ṳ' => 'ṳ', - 'Ṵ' => 'Ṵ', - 'ṵ' => 'ṵ', - 'Ṷ' => 'Ṷ', - 'ṷ' => 'ṷ', - 'Ṹ' => 'Ṹ', - 'ṹ' => 'ṹ', - 'Ṻ' => 'Ṻ', - 'ṻ' => 'ṻ', - 'Ṽ' => 'Ṽ', - 'ṽ' => 'ṽ', - 'Ṿ' => 'Ṿ', - 'ṿ' => 'ṿ', - 'Ẁ' => 'Ẁ', - 'ẁ' => 'ẁ', - 'Ẃ' => 'Ẃ', - 'ẃ' => 'ẃ', - 'Ẅ' => 'Ẅ', - 'ẅ' => 'ẅ', - 'Ẇ' => 'Ẇ', - 'ẇ' => 'ẇ', - 'Ẉ' => 'Ẉ', - 'ẉ' => 'ẉ', - 'Ẋ' => 'Ẋ', - 'ẋ' => 'ẋ', - 'Ẍ' => 'Ẍ', - 'ẍ' => 'ẍ', - 'Ẏ' => 'Ẏ', - 'ẏ' => 'ẏ', - 'Ẑ' => 'Ẑ', - 'ẑ' => 'ẑ', - 'Ẓ' => 'Ẓ', - 'ẓ' => 'ẓ', - 'Ẕ' => 'Ẕ', - 'ẕ' => 'ẕ', - 'ẖ' => 'ẖ', - 'ẗ' => 'ẗ', - 'ẘ' => 'ẘ', - 'ẙ' => 'ẙ', - 'ẛ' => 'ẛ', - 'Ạ' => 'Ạ', - 'ạ' => 'ạ', - 'Ả' => 'Ả', - 'ả' => 'ả', - 'Ấ' => 'Ấ', - 'ấ' => 'ấ', - 'Ầ' => 'Ầ', - 'ầ' => 'ầ', - 'Ẩ' => 'Ẩ', - 'ẩ' => 'ẩ', - 'Ẫ' => 'Ẫ', - 'ẫ' => 'ẫ', - 'Ậ' => 'Ậ', - 'ậ' => 'ậ', - 'Ắ' => 'Ắ', - 'ắ' => 'ắ', - 'Ằ' => 'Ằ', - 'ằ' => 'ằ', - 'Ẳ' => 'Ẳ', - 'ẳ' => 'ẳ', - 'Ẵ' => 'Ẵ', - 'ẵ' => 'ẵ', - 'Ặ' => 'Ặ', - 'ặ' => 'ặ', - 'Ẹ' => 'Ẹ', - 'ẹ' => 'ẹ', - 'Ẻ' => 'Ẻ', - 'ẻ' => 'ẻ', - 'Ẽ' => 'Ẽ', - 'ẽ' => 'ẽ', - 'Ế' => 'Ế', - 'ế' => 'ế', - 'Ề' => 'Ề', - 'ề' => 'ề', - 'Ể' => 'Ể', - 'ể' => 'ể', - 'Ễ' => 'Ễ', - 'ễ' => 'ễ', - 'Ệ' => 'Ệ', - 'ệ' => 'ệ', - 'Ỉ' => 'Ỉ', - 'ỉ' => 'ỉ', - 'Ị' => 'Ị', - 'ị' => 'ị', - 'Ọ' => 'Ọ', - 'ọ' => 'ọ', - 'Ỏ' => 'Ỏ', - 'ỏ' => 'ỏ', - 'Ố' => 'Ố', - 'ố' => 'ố', - 'Ồ' => 'Ồ', - 'ồ' => 'ồ', - 'Ổ' => 'Ổ', - 'ổ' => 'ổ', - 'Ỗ' => 'Ỗ', - 'ỗ' => 'ỗ', - 'Ộ' => 'Ộ', - 'ộ' => 'ộ', - 'Ớ' => 'Ớ', - 'ớ' => 'ớ', - 'Ờ' => 'Ờ', - 'ờ' => 'ờ', - 'Ở' => 'Ở', - 'ở' => 'ở', - 'Ỡ' => 'Ỡ', - 'ỡ' => 'ỡ', - 'Ợ' => 'Ợ', - 'ợ' => 'ợ', - 'Ụ' => 'Ụ', - 'ụ' => 'ụ', - 'Ủ' => 'Ủ', - 'ủ' => 'ủ', - 'Ứ' => 'Ứ', - 'ứ' => 'ứ', - 'Ừ' => 'Ừ', - 'ừ' => 'ừ', - 'Ử' => 'Ử', - 'ử' => 'ử', - 'Ữ' => 'Ữ', - 'ữ' => 'ữ', - 'Ự' => 'Ự', - 'ự' => 'ự', - 'Ỳ' => 'Ỳ', - 'ỳ' => 'ỳ', - 'Ỵ' => 'Ỵ', - 'ỵ' => 'ỵ', - 'Ỷ' => 'Ỷ', - 'ỷ' => 'ỷ', - 'Ỹ' => 'Ỹ', - 'ỹ' => 'ỹ', - 'ἀ' => 'ἀ', - 'ἁ' => 'ἁ', - 'ἂ' => 'ἂ', - 'ἃ' => 'ἃ', - 'ἄ' => 'ἄ', - 'ἅ' => 'ἅ', - 'ἆ' => 'ἆ', - 'ἇ' => 'ἇ', - 'Ἀ' => 'Ἀ', - 'Ἁ' => 'Ἁ', - 'Ἂ' => 'Ἂ', - 'Ἃ' => 'Ἃ', - 'Ἄ' => 'Ἄ', - 'Ἅ' => 'Ἅ', - 'Ἆ' => 'Ἆ', - 'Ἇ' => 'Ἇ', - 'ἐ' => 'ἐ', - 'ἑ' => 'ἑ', - 'ἒ' => 'ἒ', - 'ἓ' => 'ἓ', - 'ἔ' => 'ἔ', - 'ἕ' => 'ἕ', - 'Ἐ' => 'Ἐ', - 'Ἑ' => 'Ἑ', - 'Ἒ' => 'Ἒ', - 'Ἓ' => 'Ἓ', - 'Ἔ' => 'Ἔ', - 'Ἕ' => 'Ἕ', - 'ἠ' => 'ἠ', - 'ἡ' => 'ἡ', - 'ἢ' => 'ἢ', - 'ἣ' => 'ἣ', - 'ἤ' => 'ἤ', - 'ἥ' => 'ἥ', - 'ἦ' => 'ἦ', - 'ἧ' => 'ἧ', - 'Ἠ' => 'Ἠ', - 'Ἡ' => 'Ἡ', - 'Ἢ' => 'Ἢ', - 'Ἣ' => 'Ἣ', - 'Ἤ' => 'Ἤ', - 'Ἥ' => 'Ἥ', - 'Ἦ' => 'Ἦ', - 'Ἧ' => 'Ἧ', - 'ἰ' => 'ἰ', - 'ἱ' => 'ἱ', - 'ἲ' => 'ἲ', - 'ἳ' => 'ἳ', - 'ἴ' => 'ἴ', - 'ἵ' => 'ἵ', - 'ἶ' => 'ἶ', - 'ἷ' => 'ἷ', - 'Ἰ' => 'Ἰ', - 'Ἱ' => 'Ἱ', - 'Ἲ' => 'Ἲ', - 'Ἳ' => 'Ἳ', - 'Ἴ' => 'Ἴ', - 'Ἵ' => 'Ἵ', - 'Ἶ' => 'Ἶ', - 'Ἷ' => 'Ἷ', - 'ὀ' => 'ὀ', - 'ὁ' => 'ὁ', - 'ὂ' => 'ὂ', - 'ὃ' => 'ὃ', - 'ὄ' => 'ὄ', - 'ὅ' => 'ὅ', - 'Ὀ' => 'Ὀ', - 'Ὁ' => 'Ὁ', - 'Ὂ' => 'Ὂ', - 'Ὃ' => 'Ὃ', - 'Ὄ' => 'Ὄ', - 'Ὅ' => 'Ὅ', - 'ὐ' => 'ὐ', - 'ὑ' => 'ὑ', - 'ὒ' => 'ὒ', - 'ὓ' => 'ὓ', - 'ὔ' => 'ὔ', - 'ὕ' => 'ὕ', - 'ὖ' => 'ὖ', - 'ὗ' => 'ὗ', - 'Ὑ' => 'Ὑ', - 'Ὓ' => 'Ὓ', - 'Ὕ' => 'Ὕ', - 'Ὗ' => 'Ὗ', - 'ὠ' => 'ὠ', - 'ὡ' => 'ὡ', - 'ὢ' => 'ὢ', - 'ὣ' => 'ὣ', - 'ὤ' => 'ὤ', - 'ὥ' => 'ὥ', - 'ὦ' => 'ὦ', - 'ὧ' => 'ὧ', - 'Ὠ' => 'Ὠ', - 'Ὡ' => 'Ὡ', - 'Ὢ' => 'Ὢ', - 'Ὣ' => 'Ὣ', - 'Ὤ' => 'Ὤ', - 'Ὥ' => 'Ὥ', - 'Ὦ' => 'Ὦ', - 'Ὧ' => 'Ὧ', - 'ὰ' => 'ὰ', - 'ά' => 'ά', - 'ὲ' => 'ὲ', - 'έ' => 'έ', - 'ὴ' => 'ὴ', - 'ή' => 'ή', - 'ὶ' => 'ὶ', - 'ί' => 'ί', - 'ὸ' => 'ὸ', - 'ό' => 'ό', - 'ὺ' => 'ὺ', - 'ύ' => 'ύ', - 'ὼ' => 'ὼ', - 'ώ' => 'ώ', - 'ᾀ' => 'ᾀ', - 'ᾁ' => 'ᾁ', - 'ᾂ' => 'ᾂ', - 'ᾃ' => 'ᾃ', - 'ᾄ' => 'ᾄ', - 'ᾅ' => 'ᾅ', - 'ᾆ' => 'ᾆ', - 'ᾇ' => 'ᾇ', - 'ᾈ' => 'ᾈ', - 'ᾉ' => 'ᾉ', - 'ᾊ' => 'ᾊ', - 'ᾋ' => 'ᾋ', - 'ᾌ' => 'ᾌ', - 'ᾍ' => 'ᾍ', - 'ᾎ' => 'ᾎ', - 'ᾏ' => 'ᾏ', - 'ᾐ' => 'ᾐ', - 'ᾑ' => 'ᾑ', - 'ᾒ' => 'ᾒ', - 'ᾓ' => 'ᾓ', - 'ᾔ' => 'ᾔ', - 'ᾕ' => 'ᾕ', - 'ᾖ' => 'ᾖ', - 'ᾗ' => 'ᾗ', - 'ᾘ' => 'ᾘ', - 'ᾙ' => 'ᾙ', - 'ᾚ' => 'ᾚ', - 'ᾛ' => 'ᾛ', - 'ᾜ' => 'ᾜ', - 'ᾝ' => 'ᾝ', - 'ᾞ' => 'ᾞ', - 'ᾟ' => 'ᾟ', - 'ᾠ' => 'ᾠ', - 'ᾡ' => 'ᾡ', - 'ᾢ' => 'ᾢ', - 'ᾣ' => 'ᾣ', - 'ᾤ' => 'ᾤ', - 'ᾥ' => 'ᾥ', - 'ᾦ' => 'ᾦ', - 'ᾧ' => 'ᾧ', - 'ᾨ' => 'ᾨ', - 'ᾩ' => 'ᾩ', - 'ᾪ' => 'ᾪ', - 'ᾫ' => 'ᾫ', - 'ᾬ' => 'ᾬ', - 'ᾭ' => 'ᾭ', - 'ᾮ' => 'ᾮ', - 'ᾯ' => 'ᾯ', - 'ᾰ' => 'ᾰ', - 'ᾱ' => 'ᾱ', - 'ᾲ' => 'ᾲ', - 'ᾳ' => 'ᾳ', - 'ᾴ' => 'ᾴ', - 'ᾶ' => 'ᾶ', - 'ᾷ' => 'ᾷ', - 'Ᾰ' => 'Ᾰ', - 'Ᾱ' => 'Ᾱ', - 'Ὰ' => 'Ὰ', - 'Ά' => 'Ά', - 'ᾼ' => 'ᾼ', - 'ι' => 'ι', - '῁' => '῁', - 'ῂ' => 'ῂ', - 'ῃ' => 'ῃ', - 'ῄ' => 'ῄ', - 'ῆ' => 'ῆ', - 'ῇ' => 'ῇ', - 'Ὲ' => 'Ὲ', - 'Έ' => 'Έ', - 'Ὴ' => 'Ὴ', - 'Ή' => 'Ή', - 'ῌ' => 'ῌ', - '῍' => '῍', - '῎' => '῎', - '῏' => '῏', - 'ῐ' => 'ῐ', - 'ῑ' => 'ῑ', - 'ῒ' => 'ῒ', - 'ΐ' => 'ΐ', - 'ῖ' => 'ῖ', - 'ῗ' => 'ῗ', - 'Ῐ' => 'Ῐ', - 'Ῑ' => 'Ῑ', - 'Ὶ' => 'Ὶ', - 'Ί' => 'Ί', - '῝' => '῝', - '῞' => '῞', - '῟' => '῟', - 'ῠ' => 'ῠ', - 'ῡ' => 'ῡ', - 'ῢ' => 'ῢ', - 'ΰ' => 'ΰ', - 'ῤ' => 'ῤ', - 'ῥ' => 'ῥ', - 'ῦ' => 'ῦ', - 'ῧ' => 'ῧ', - 'Ῠ' => 'Ῠ', - 'Ῡ' => 'Ῡ', - 'Ὺ' => 'Ὺ', - 'Ύ' => 'Ύ', - 'Ῥ' => 'Ῥ', - '῭' => '῭', - '΅' => '΅', - '`' => '`', - 'ῲ' => 'ῲ', - 'ῳ' => 'ῳ', - 'ῴ' => 'ῴ', - 'ῶ' => 'ῶ', - 'ῷ' => 'ῷ', - 'Ὸ' => 'Ὸ', - 'Ό' => 'Ό', - 'Ὼ' => 'Ὼ', - 'Ώ' => 'Ώ', - 'ῼ' => 'ῼ', - '´' => '´', - ' ' => ' ', - ' ' => ' ', - 'Ω' => 'Ω', - 'K' => 'K', - 'Å' => 'Å', - '↚' => '↚', - '↛' => '↛', - '↮' => '↮', - '⇍' => '⇍', - '⇎' => '⇎', - '⇏' => '⇏', - '∄' => '∄', - '∉' => '∉', - '∌' => '∌', - '∤' => '∤', - '∦' => '∦', - '≁' => '≁', - '≄' => '≄', - '≇' => '≇', - '≉' => '≉', - '≠' => '≠', - '≢' => '≢', - '≭' => '≭', - '≮' => '≮', - '≯' => '≯', - '≰' => '≰', - '≱' => '≱', - '≴' => '≴', - '≵' => '≵', - '≸' => '≸', - '≹' => '≹', - '⊀' => '⊀', - '⊁' => '⊁', - '⊄' => '⊄', - '⊅' => '⊅', - '⊈' => '⊈', - '⊉' => '⊉', - '⊬' => '⊬', - '⊭' => '⊭', - '⊮' => '⊮', - '⊯' => '⊯', - '⋠' => '⋠', - '⋡' => '⋡', - '⋢' => '⋢', - '⋣' => '⋣', - '⋪' => '⋪', - '⋫' => '⋫', - '⋬' => '⋬', - '⋭' => '⋭', - '〈' => '〈', - '〉' => '〉', - '⫝̸' => '⫝̸', - 'が' => 'が', - 'ぎ' => 'ぎ', - 'ぐ' => 'ぐ', - 'げ' => 'げ', - 'ご' => 'ご', - 'ざ' => 'ざ', - 'じ' => 'じ', - 'ず' => 'ず', - 'ぜ' => 'ぜ', - 'ぞ' => 'ぞ', - 'だ' => 'だ', - 'ぢ' => 'ぢ', - 'づ' => 'づ', - 'で' => 'で', - 'ど' => 'ど', - 'ば' => 'ば', - 'ぱ' => 'ぱ', - 'び' => 'び', - 'ぴ' => 'ぴ', - 'ぶ' => 'ぶ', - 'ぷ' => 'ぷ', - 'べ' => 'べ', - 'ぺ' => 'ぺ', - 'ぼ' => 'ぼ', - 'ぽ' => 'ぽ', - 'ゔ' => 'ゔ', - 'ゞ' => 'ゞ', - 'ガ' => 'ガ', - 'ギ' => 'ギ', - 'グ' => 'グ', - 'ゲ' => 'ゲ', - 'ゴ' => 'ゴ', - 'ザ' => 'ザ', - 'ジ' => 'ジ', - 'ズ' => 'ズ', - 'ゼ' => 'ゼ', - 'ゾ' => 'ゾ', - 'ダ' => 'ダ', - 'ヂ' => 'ヂ', - 'ヅ' => 'ヅ', - 'デ' => 'デ', - 'ド' => 'ド', - 'バ' => 'バ', - 'パ' => 'パ', - 'ビ' => 'ビ', - 'ピ' => 'ピ', - 'ブ' => 'ブ', - 'プ' => 'プ', - 'ベ' => 'ベ', - 'ペ' => 'ペ', - 'ボ' => 'ボ', - 'ポ' => 'ポ', - 'ヴ' => 'ヴ', - 'ヷ' => 'ヷ', - 'ヸ' => 'ヸ', - 'ヹ' => 'ヹ', - 'ヺ' => 'ヺ', - 'ヾ' => 'ヾ', - '豈' => '豈', - '更' => '更', - '車' => '車', - '賈' => '賈', - '滑' => '滑', - '串' => '串', - '句' => '句', - '龜' => '龜', - '龜' => '龜', - '契' => '契', - '金' => '金', - '喇' => '喇', - '奈' => '奈', - '懶' => '懶', - '癩' => '癩', - '羅' => '羅', - '蘿' => '蘿', - '螺' => '螺', - '裸' => '裸', - '邏' => '邏', - '樂' => '樂', - '洛' => '洛', - '烙' => '烙', - '珞' => '珞', - '落' => '落', - '酪' => '酪', - '駱' => '駱', - '亂' => '亂', - '卵' => '卵', - '欄' => '欄', - '爛' => '爛', - '蘭' => '蘭', - '鸞' => '鸞', - '嵐' => '嵐', - '濫' => '濫', - '藍' => '藍', - '襤' => '襤', - '拉' => '拉', - '臘' => '臘', - '蠟' => '蠟', - '廊' => '廊', - '朗' => '朗', - '浪' => '浪', - '狼' => '狼', - '郎' => '郎', - '來' => '來', - '冷' => '冷', - '勞' => '勞', - '擄' => '擄', - '櫓' => '櫓', - '爐' => '爐', - '盧' => '盧', - '老' => '老', - '蘆' => '蘆', - '虜' => '虜', - '路' => '路', - '露' => '露', - '魯' => '魯', - '鷺' => '鷺', - '碌' => '碌', - '祿' => '祿', - '綠' => '綠', - '菉' => '菉', - '錄' => '錄', - '鹿' => '鹿', - '論' => '論', - '壟' => '壟', - '弄' => '弄', - '籠' => '籠', - '聾' => '聾', - '牢' => '牢', - '磊' => '磊', - '賂' => '賂', - '雷' => '雷', - '壘' => '壘', - '屢' => '屢', - '樓' => '樓', - '淚' => '淚', - '漏' => '漏', - '累' => '累', - '縷' => '縷', - '陋' => '陋', - '勒' => '勒', - '肋' => '肋', - '凜' => '凜', - '凌' => '凌', - '稜' => '稜', - '綾' => '綾', - '菱' => '菱', - '陵' => '陵', - '讀' => '讀', - '拏' => '拏', - '樂' => '樂', - '諾' => '諾', - '丹' => '丹', - '寧' => '寧', - '怒' => '怒', - '率' => '率', - '異' => '異', - '北' => '北', - '磻' => '磻', - '便' => '便', - '復' => '復', - '不' => '不', - '泌' => '泌', - '數' => '數', - '索' => '索', - '參' => '參', - '塞' => '塞', - '省' => '省', - '葉' => '葉', - '說' => '說', - '殺' => '殺', - '辰' => '辰', - '沈' => '沈', - '拾' => '拾', - '若' => '若', - '掠' => '掠', - '略' => '略', - '亮' => '亮', - '兩' => '兩', - '凉' => '凉', - '梁' => '梁', - '糧' => '糧', - '良' => '良', - '諒' => '諒', - '量' => '量', - '勵' => '勵', - '呂' => '呂', - '女' => '女', - '廬' => '廬', - '旅' => '旅', - '濾' => '濾', - '礪' => '礪', - '閭' => '閭', - '驪' => '驪', - '麗' => '麗', - '黎' => '黎', - '力' => '力', - '曆' => '曆', - '歷' => '歷', - '轢' => '轢', - '年' => '年', - '憐' => '憐', - '戀' => '戀', - '撚' => '撚', - '漣' => '漣', - '煉' => '煉', - '璉' => '璉', - '秊' => '秊', - '練' => '練', - '聯' => '聯', - '輦' => '輦', - '蓮' => '蓮', - '連' => '連', - '鍊' => '鍊', - '列' => '列', - '劣' => '劣', - '咽' => '咽', - '烈' => '烈', - '裂' => '裂', - '說' => '說', - '廉' => '廉', - '念' => '念', - '捻' => '捻', - '殮' => '殮', - '簾' => '簾', - '獵' => '獵', - '令' => '令', - '囹' => '囹', - '寧' => '寧', - '嶺' => '嶺', - '怜' => '怜', - '玲' => '玲', - '瑩' => '瑩', - '羚' => '羚', - '聆' => '聆', - '鈴' => '鈴', - '零' => '零', - '靈' => '靈', - '領' => '領', - '例' => '例', - '禮' => '禮', - '醴' => '醴', - '隸' => '隸', - '惡' => '惡', - '了' => '了', - '僚' => '僚', - '寮' => '寮', - '尿' => '尿', - '料' => '料', - '樂' => '樂', - '燎' => '燎', - '療' => '療', - '蓼' => '蓼', - '遼' => '遼', - '龍' => '龍', - '暈' => '暈', - '阮' => '阮', - '劉' => '劉', - '杻' => '杻', - '柳' => '柳', - '流' => '流', - '溜' => '溜', - '琉' => '琉', - '留' => '留', - '硫' => '硫', - '紐' => '紐', - '類' => '類', - '六' => '六', - '戮' => '戮', - '陸' => '陸', - '倫' => '倫', - '崙' => '崙', - '淪' => '淪', - '輪' => '輪', - '律' => '律', - '慄' => '慄', - '栗' => '栗', - '率' => '率', - '隆' => '隆', - '利' => '利', - '吏' => '吏', - '履' => '履', - '易' => '易', - '李' => '李', - '梨' => '梨', - '泥' => '泥', - '理' => '理', - '痢' => '痢', - '罹' => '罹', - '裏' => '裏', - '裡' => '裡', - '里' => '里', - '離' => '離', - '匿' => '匿', - '溺' => '溺', - '吝' => '吝', - '燐' => '燐', - '璘' => '璘', - '藺' => '藺', - '隣' => '隣', - '鱗' => '鱗', - '麟' => '麟', - '林' => '林', - '淋' => '淋', - '臨' => '臨', - '立' => '立', - '笠' => '笠', - '粒' => '粒', - '狀' => '狀', - '炙' => '炙', - '識' => '識', - '什' => '什', - '茶' => '茶', - '刺' => '刺', - '切' => '切', - '度' => '度', - '拓' => '拓', - '糖' => '糖', - '宅' => '宅', - '洞' => '洞', - '暴' => '暴', - '輻' => '輻', - '行' => '行', - '降' => '降', - '見' => '見', - '廓' => '廓', - '兀' => '兀', - '嗀' => '嗀', - '塚' => '塚', - '晴' => '晴', - '凞' => '凞', - '猪' => '猪', - '益' => '益', - '礼' => '礼', - '神' => '神', - '祥' => '祥', - '福' => '福', - '靖' => '靖', - '精' => '精', - '羽' => '羽', - '蘒' => '蘒', - '諸' => '諸', - '逸' => '逸', - '都' => '都', - '飯' => '飯', - '飼' => '飼', - '館' => '館', - '鶴' => '鶴', - '郞' => '郞', - '隷' => '隷', - '侮' => '侮', - '僧' => '僧', - '免' => '免', - '勉' => '勉', - '勤' => '勤', - '卑' => '卑', - '喝' => '喝', - '嘆' => '嘆', - '器' => '器', - '塀' => '塀', - '墨' => '墨', - '層' => '層', - '屮' => '屮', - '悔' => '悔', - '慨' => '慨', - '憎' => '憎', - '懲' => '懲', - '敏' => '敏', - '既' => '既', - '暑' => '暑', - '梅' => '梅', - '海' => '海', - '渚' => '渚', - '漢' => '漢', - '煮' => '煮', - '爫' => '爫', - '琢' => '琢', - '碑' => '碑', - '社' => '社', - '祉' => '祉', - '祈' => '祈', - '祐' => '祐', - '祖' => '祖', - '祝' => '祝', - '禍' => '禍', - '禎' => '禎', - '穀' => '穀', - '突' => '突', - '節' => '節', - '練' => '練', - '縉' => '縉', - '繁' => '繁', - '署' => '署', - '者' => '者', - '臭' => '臭', - '艹' => '艹', - '艹' => '艹', - '著' => '著', - '褐' => '褐', - '視' => '視', - '謁' => '謁', - '謹' => '謹', - '賓' => '賓', - '贈' => '贈', - '辶' => '辶', - '逸' => '逸', - '難' => '難', - '響' => '響', - '頻' => '頻', - '恵' => '恵', - '𤋮' => '𤋮', - '舘' => '舘', - '並' => '並', - '况' => '况', - '全' => '全', - '侀' => '侀', - '充' => '充', - '冀' => '冀', - '勇' => '勇', - '勺' => '勺', - '喝' => '喝', - '啕' => '啕', - '喙' => '喙', - '嗢' => '嗢', - '塚' => '塚', - '墳' => '墳', - '奄' => '奄', - '奔' => '奔', - '婢' => '婢', - '嬨' => '嬨', - '廒' => '廒', - '廙' => '廙', - '彩' => '彩', - '徭' => '徭', - '惘' => '惘', - '慎' => '慎', - '愈' => '愈', - '憎' => '憎', - '慠' => '慠', - '懲' => '懲', - '戴' => '戴', - '揄' => '揄', - '搜' => '搜', - '摒' => '摒', - '敖' => '敖', - '晴' => '晴', - '朗' => '朗', - '望' => '望', - '杖' => '杖', - '歹' => '歹', - '殺' => '殺', - '流' => '流', - '滛' => '滛', - '滋' => '滋', - '漢' => '漢', - '瀞' => '瀞', - '煮' => '煮', - '瞧' => '瞧', - '爵' => '爵', - '犯' => '犯', - '猪' => '猪', - '瑱' => '瑱', - '甆' => '甆', - '画' => '画', - '瘝' => '瘝', - '瘟' => '瘟', - '益' => '益', - '盛' => '盛', - '直' => '直', - '睊' => '睊', - '着' => '着', - '磌' => '磌', - '窱' => '窱', - '節' => '節', - '类' => '类', - '絛' => '絛', - '練' => '練', - '缾' => '缾', - '者' => '者', - '荒' => '荒', - '華' => '華', - '蝹' => '蝹', - '襁' => '襁', - '覆' => '覆', - '視' => '視', - '調' => '調', - '諸' => '諸', - '請' => '請', - '謁' => '謁', - '諾' => '諾', - '諭' => '諭', - '謹' => '謹', - '變' => '變', - '贈' => '贈', - '輸' => '輸', - '遲' => '遲', - '醙' => '醙', - '鉶' => '鉶', - '陼' => '陼', - '難' => '難', - '靖' => '靖', - '韛' => '韛', - '響' => '響', - '頋' => '頋', - '頻' => '頻', - '鬒' => '鬒', - '龜' => '龜', - '𢡊' => '𢡊', - '𢡄' => '𢡄', - '𣏕' => '𣏕', - '㮝' => '㮝', - '䀘' => '䀘', - '䀹' => '䀹', - '𥉉' => '𥉉', - '𥳐' => '𥳐', - '𧻓' => '𧻓', - '齃' => '齃', - '龎' => '龎', - 'יִ' => 'יִ', - 'ײַ' => 'ײַ', - 'שׁ' => 'שׁ', - 'שׂ' => 'שׂ', - 'שּׁ' => 'שּׁ', - 'שּׂ' => 'שּׂ', - 'אַ' => 'אַ', - 'אָ' => 'אָ', - 'אּ' => 'אּ', - 'בּ' => 'בּ', - 'גּ' => 'גּ', - 'דּ' => 'דּ', - 'הּ' => 'הּ', - 'וּ' => 'וּ', - 'זּ' => 'זּ', - 'טּ' => 'טּ', - 'יּ' => 'יּ', - 'ךּ' => 'ךּ', - 'כּ' => 'כּ', - 'לּ' => 'לּ', - 'מּ' => 'מּ', - 'נּ' => 'נּ', - 'סּ' => 'סּ', - 'ףּ' => 'ףּ', - 'פּ' => 'פּ', - 'צּ' => 'צּ', - 'קּ' => 'קּ', - 'רּ' => 'רּ', - 'שּ' => 'שּ', - 'תּ' => 'תּ', - 'וֹ' => 'וֹ', - 'בֿ' => 'בֿ', - 'כֿ' => 'כֿ', - 'פֿ' => 'פֿ', - '𑂚' => '𑂚', - '𑂜' => '𑂜', - '𑂫' => '𑂫', - '𑄮' => '𑄮', - '𑄯' => '𑄯', - '𑍋' => '𑍋', - '𑍌' => '𑍌', - '𑒻' => '𑒻', - '𑒼' => '𑒼', - '𑒾' => '𑒾', - '𑖺' => '𑖺', - '𑖻' => '𑖻', - '𑤸' => '𑤸', - '𝅗𝅥' => '𝅗𝅥', - '𝅘𝅥' => '𝅘𝅥', - '𝅘𝅥𝅮' => '𝅘𝅥𝅮', - '𝅘𝅥𝅯' => '𝅘𝅥𝅯', - '𝅘𝅥𝅰' => '𝅘𝅥𝅰', - '𝅘𝅥𝅱' => '𝅘𝅥𝅱', - '𝅘𝅥𝅲' => '𝅘𝅥𝅲', - '𝆹𝅥' => '𝆹𝅥', - '𝆺𝅥' => '𝆺𝅥', - '𝆹𝅥𝅮' => '𝆹𝅥𝅮', - '𝆺𝅥𝅮' => '𝆺𝅥𝅮', - '𝆹𝅥𝅯' => '𝆹𝅥𝅯', - '𝆺𝅥𝅯' => '𝆺𝅥𝅯', - '丽' => '丽', - '丸' => '丸', - '乁' => '乁', - '𠄢' => '𠄢', - '你' => '你', - '侮' => '侮', - '侻' => '侻', - '倂' => '倂', - '偺' => '偺', - '備' => '備', - '僧' => '僧', - '像' => '像', - '㒞' => '㒞', - '𠘺' => '𠘺', - '免' => '免', - '兔' => '兔', - '兤' => '兤', - '具' => '具', - '𠔜' => '𠔜', - '㒹' => '㒹', - '內' => '內', - '再' => '再', - '𠕋' => '𠕋', - '冗' => '冗', - '冤' => '冤', - '仌' => '仌', - '冬' => '冬', - '况' => '况', - '𩇟' => '𩇟', - '凵' => '凵', - '刃' => '刃', - '㓟' => '㓟', - '刻' => '刻', - '剆' => '剆', - '割' => '割', - '剷' => '剷', - '㔕' => '㔕', - '勇' => '勇', - '勉' => '勉', - '勤' => '勤', - '勺' => '勺', - '包' => '包', - '匆' => '匆', - '北' => '北', - '卉' => '卉', - '卑' => '卑', - '博' => '博', - '即' => '即', - '卽' => '卽', - '卿' => '卿', - '卿' => '卿', - '卿' => '卿', - '𠨬' => '𠨬', - '灰' => '灰', - '及' => '及', - '叟' => '叟', - '𠭣' => '𠭣', - '叫' => '叫', - '叱' => '叱', - '吆' => '吆', - '咞' => '咞', - '吸' => '吸', - '呈' => '呈', - '周' => '周', - '咢' => '咢', - '哶' => '哶', - '唐' => '唐', - '啓' => '啓', - '啣' => '啣', - '善' => '善', - '善' => '善', - '喙' => '喙', - '喫' => '喫', - '喳' => '喳', - '嗂' => '嗂', - '圖' => '圖', - '嘆' => '嘆', - '圗' => '圗', - '噑' => '噑', - '噴' => '噴', - '切' => '切', - '壮' => '壮', - '城' => '城', - '埴' => '埴', - '堍' => '堍', - '型' => '型', - '堲' => '堲', - '報' => '報', - '墬' => '墬', - '𡓤' => '𡓤', - '売' => '売', - '壷' => '壷', - '夆' => '夆', - '多' => '多', - '夢' => '夢', - '奢' => '奢', - '𡚨' => '𡚨', - '𡛪' => '𡛪', - '姬' => '姬', - '娛' => '娛', - '娧' => '娧', - '姘' => '姘', - '婦' => '婦', - '㛮' => '㛮', - '㛼' => '㛼', - '嬈' => '嬈', - '嬾' => '嬾', - '嬾' => '嬾', - '𡧈' => '𡧈', - '寃' => '寃', - '寘' => '寘', - '寧' => '寧', - '寳' => '寳', - '𡬘' => '𡬘', - '寿' => '寿', - '将' => '将', - '当' => '当', - '尢' => '尢', - '㞁' => '㞁', - '屠' => '屠', - '屮' => '屮', - '峀' => '峀', - '岍' => '岍', - '𡷤' => '𡷤', - '嵃' => '嵃', - '𡷦' => '𡷦', - '嵮' => '嵮', - '嵫' => '嵫', - '嵼' => '嵼', - '巡' => '巡', - '巢' => '巢', - '㠯' => '㠯', - '巽' => '巽', - '帨' => '帨', - '帽' => '帽', - '幩' => '幩', - '㡢' => '㡢', - '𢆃' => '𢆃', - '㡼' => '㡼', - '庰' => '庰', - '庳' => '庳', - '庶' => '庶', - '廊' => '廊', - '𪎒' => '𪎒', - '廾' => '廾', - '𢌱' => '𢌱', - '𢌱' => '𢌱', - '舁' => '舁', - '弢' => '弢', - '弢' => '弢', - '㣇' => '㣇', - '𣊸' => '𣊸', - '𦇚' => '𦇚', - '形' => '形', - '彫' => '彫', - '㣣' => '㣣', - '徚' => '徚', - '忍' => '忍', - '志' => '志', - '忹' => '忹', - '悁' => '悁', - '㤺' => '㤺', - '㤜' => '㤜', - '悔' => '悔', - '𢛔' => '𢛔', - '惇' => '惇', - '慈' => '慈', - '慌' => '慌', - '慎' => '慎', - '慌' => '慌', - '慺' => '慺', - '憎' => '憎', - '憲' => '憲', - '憤' => '憤', - '憯' => '憯', - '懞' => '懞', - '懲' => '懲', - '懶' => '懶', - '成' => '成', - '戛' => '戛', - '扝' => '扝', - '抱' => '抱', - '拔' => '拔', - '捐' => '捐', - '𢬌' => '𢬌', - '挽' => '挽', - '拼' => '拼', - '捨' => '捨', - '掃' => '掃', - '揤' => '揤', - '𢯱' => '𢯱', - '搢' => '搢', - '揅' => '揅', - '掩' => '掩', - '㨮' => '㨮', - '摩' => '摩', - '摾' => '摾', - '撝' => '撝', - '摷' => '摷', - '㩬' => '㩬', - '敏' => '敏', - '敬' => '敬', - '𣀊' => '𣀊', - '旣' => '旣', - '書' => '書', - '晉' => '晉', - '㬙' => '㬙', - '暑' => '暑', - '㬈' => '㬈', - '㫤' => '㫤', - '冒' => '冒', - '冕' => '冕', - '最' => '最', - '暜' => '暜', - '肭' => '肭', - '䏙' => '䏙', - '朗' => '朗', - '望' => '望', - '朡' => '朡', - '杞' => '杞', - '杓' => '杓', - '𣏃' => '𣏃', - '㭉' => '㭉', - '柺' => '柺', - '枅' => '枅', - '桒' => '桒', - '梅' => '梅', - '𣑭' => '𣑭', - '梎' => '梎', - '栟' => '栟', - '椔' => '椔', - '㮝' => '㮝', - '楂' => '楂', - '榣' => '榣', - '槪' => '槪', - '檨' => '檨', - '𣚣' => '𣚣', - '櫛' => '櫛', - '㰘' => '㰘', - '次' => '次', - '𣢧' => '𣢧', - '歔' => '歔', - '㱎' => '㱎', - '歲' => '歲', - '殟' => '殟', - '殺' => '殺', - '殻' => '殻', - '𣪍' => '𣪍', - '𡴋' => '𡴋', - '𣫺' => '𣫺', - '汎' => '汎', - '𣲼' => '𣲼', - '沿' => '沿', - '泍' => '泍', - '汧' => '汧', - '洖' => '洖', - '派' => '派', - '海' => '海', - '流' => '流', - '浩' => '浩', - '浸' => '浸', - '涅' => '涅', - '𣴞' => '𣴞', - '洴' => '洴', - '港' => '港', - '湮' => '湮', - '㴳' => '㴳', - '滋' => '滋', - '滇' => '滇', - '𣻑' => '𣻑', - '淹' => '淹', - '潮' => '潮', - '𣽞' => '𣽞', - '𣾎' => '𣾎', - '濆' => '濆', - '瀹' => '瀹', - '瀞' => '瀞', - '瀛' => '瀛', - '㶖' => '㶖', - '灊' => '灊', - '災' => '災', - '灷' => '灷', - '炭' => '炭', - '𠔥' => '𠔥', - '煅' => '煅', - '𤉣' => '𤉣', - '熜' => '熜', - '𤎫' => '𤎫', - '爨' => '爨', - '爵' => '爵', - '牐' => '牐', - '𤘈' => '𤘈', - '犀' => '犀', - '犕' => '犕', - '𤜵' => '𤜵', - '𤠔' => '𤠔', - '獺' => '獺', - '王' => '王', - '㺬' => '㺬', - '玥' => '玥', - '㺸' => '㺸', - '㺸' => '㺸', - '瑇' => '瑇', - '瑜' => '瑜', - '瑱' => '瑱', - '璅' => '璅', - '瓊' => '瓊', - '㼛' => '㼛', - '甤' => '甤', - '𤰶' => '𤰶', - '甾' => '甾', - '𤲒' => '𤲒', - '異' => '異', - '𢆟' => '𢆟', - '瘐' => '瘐', - '𤾡' => '𤾡', - '𤾸' => '𤾸', - '𥁄' => '𥁄', - '㿼' => '㿼', - '䀈' => '䀈', - '直' => '直', - '𥃳' => '𥃳', - '𥃲' => '𥃲', - '𥄙' => '𥄙', - '𥄳' => '𥄳', - '眞' => '眞', - '真' => '真', - '真' => '真', - '睊' => '睊', - '䀹' => '䀹', - '瞋' => '瞋', - '䁆' => '䁆', - '䂖' => '䂖', - '𥐝' => '𥐝', - '硎' => '硎', - '碌' => '碌', - '磌' => '磌', - '䃣' => '䃣', - '𥘦' => '𥘦', - '祖' => '祖', - '𥚚' => '𥚚', - '𥛅' => '𥛅', - '福' => '福', - '秫' => '秫', - '䄯' => '䄯', - '穀' => '穀', - '穊' => '穊', - '穏' => '穏', - '𥥼' => '𥥼', - '𥪧' => '𥪧', - '𥪧' => '𥪧', - '竮' => '竮', - '䈂' => '䈂', - '𥮫' => '𥮫', - '篆' => '篆', - '築' => '築', - '䈧' => '䈧', - '𥲀' => '𥲀', - '糒' => '糒', - '䊠' => '䊠', - '糨' => '糨', - '糣' => '糣', - '紀' => '紀', - '𥾆' => '𥾆', - '絣' => '絣', - '䌁' => '䌁', - '緇' => '緇', - '縂' => '縂', - '繅' => '繅', - '䌴' => '䌴', - '𦈨' => '𦈨', - '𦉇' => '𦉇', - '䍙' => '䍙', - '𦋙' => '𦋙', - '罺' => '罺', - '𦌾' => '𦌾', - '羕' => '羕', - '翺' => '翺', - '者' => '者', - '𦓚' => '𦓚', - '𦔣' => '𦔣', - '聠' => '聠', - '𦖨' => '𦖨', - '聰' => '聰', - '𣍟' => '𣍟', - '䏕' => '䏕', - '育' => '育', - '脃' => '脃', - '䐋' => '䐋', - '脾' => '脾', - '媵' => '媵', - '𦞧' => '𦞧', - '𦞵' => '𦞵', - '𣎓' => '𣎓', - '𣎜' => '𣎜', - '舁' => '舁', - '舄' => '舄', - '辞' => '辞', - '䑫' => '䑫', - '芑' => '芑', - '芋' => '芋', - '芝' => '芝', - '劳' => '劳', - '花' => '花', - '芳' => '芳', - '芽' => '芽', - '苦' => '苦', - '𦬼' => '𦬼', - '若' => '若', - '茝' => '茝', - '荣' => '荣', - '莭' => '莭', - '茣' => '茣', - '莽' => '莽', - '菧' => '菧', - '著' => '著', - '荓' => '荓', - '菊' => '菊', - '菌' => '菌', - '菜' => '菜', - '𦰶' => '𦰶', - '𦵫' => '𦵫', - '𦳕' => '𦳕', - '䔫' => '䔫', - '蓱' => '蓱', - '蓳' => '蓳', - '蔖' => '蔖', - '𧏊' => '𧏊', - '蕤' => '蕤', - '𦼬' => '𦼬', - '䕝' => '䕝', - '䕡' => '䕡', - '𦾱' => '𦾱', - '𧃒' => '𧃒', - '䕫' => '䕫', - '虐' => '虐', - '虜' => '虜', - '虧' => '虧', - '虩' => '虩', - '蚩' => '蚩', - '蚈' => '蚈', - '蜎' => '蜎', - '蛢' => '蛢', - '蝹' => '蝹', - '蜨' => '蜨', - '蝫' => '蝫', - '螆' => '螆', - '䗗' => '䗗', - '蟡' => '蟡', - '蠁' => '蠁', - '䗹' => '䗹', - '衠' => '衠', - '衣' => '衣', - '𧙧' => '𧙧', - '裗' => '裗', - '裞' => '裞', - '䘵' => '䘵', - '裺' => '裺', - '㒻' => '㒻', - '𧢮' => '𧢮', - '𧥦' => '𧥦', - '䚾' => '䚾', - '䛇' => '䛇', - '誠' => '誠', - '諭' => '諭', - '變' => '變', - '豕' => '豕', - '𧲨' => '𧲨', - '貫' => '貫', - '賁' => '賁', - '贛' => '贛', - '起' => '起', - '𧼯' => '𧼯', - '𠠄' => '𠠄', - '跋' => '跋', - '趼' => '趼', - '跰' => '跰', - '𠣞' => '𠣞', - '軔' => '軔', - '輸' => '輸', - '𨗒' => '𨗒', - '𨗭' => '𨗭', - '邔' => '邔', - '郱' => '郱', - '鄑' => '鄑', - '𨜮' => '𨜮', - '鄛' => '鄛', - '鈸' => '鈸', - '鋗' => '鋗', - '鋘' => '鋘', - '鉼' => '鉼', - '鏹' => '鏹', - '鐕' => '鐕', - '𨯺' => '𨯺', - '開' => '開', - '䦕' => '䦕', - '閷' => '閷', - '𨵷' => '𨵷', - '䧦' => '䧦', - '雃' => '雃', - '嶲' => '嶲', - '霣' => '霣', - '𩅅' => '𩅅', - '𩈚' => '𩈚', - '䩮' => '䩮', - '䩶' => '䩶', - '韠' => '韠', - '𩐊' => '𩐊', - '䪲' => '䪲', - '𩒖' => '𩒖', - '頋' => '頋', - '頋' => '頋', - '頩' => '頩', - '𩖶' => '𩖶', - '飢' => '飢', - '䬳' => '䬳', - '餩' => '餩', - '馧' => '馧', - '駂' => '駂', - '駾' => '駾', - '䯎' => '䯎', - '𩬰' => '𩬰', - '鬒' => '鬒', - '鱀' => '鱀', - '鳽' => '鳽', - '䳎' => '䳎', - '䳭' => '䳭', - '鵧' => '鵧', - '𪃎' => '𪃎', - '䳸' => '䳸', - '𪄅' => '𪄅', - '𪈎' => '𪈎', - '𪊑' => '𪊑', - '麻' => '麻', - '䵖' => '䵖', - '黹' => '黹', - '黾' => '黾', - '鼅' => '鼅', - '鼏' => '鼏', - '鼖' => '鼖', - '鼻' => '鼻', - '𪘀' => '𪘀', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php deleted file mode 100644 index ec90f36eb..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php +++ /dev/null @@ -1,876 +0,0 @@ - 230, - '́' => 230, - '̂' => 230, - '̃' => 230, - '̄' => 230, - '̅' => 230, - '̆' => 230, - '̇' => 230, - '̈' => 230, - '̉' => 230, - '̊' => 230, - '̋' => 230, - '̌' => 230, - '̍' => 230, - '̎' => 230, - '̏' => 230, - '̐' => 230, - '̑' => 230, - '̒' => 230, - '̓' => 230, - '̔' => 230, - '̕' => 232, - '̖' => 220, - '̗' => 220, - '̘' => 220, - '̙' => 220, - '̚' => 232, - '̛' => 216, - '̜' => 220, - '̝' => 220, - '̞' => 220, - '̟' => 220, - '̠' => 220, - '̡' => 202, - '̢' => 202, - '̣' => 220, - '̤' => 220, - '̥' => 220, - '̦' => 220, - '̧' => 202, - '̨' => 202, - '̩' => 220, - '̪' => 220, - '̫' => 220, - '̬' => 220, - '̭' => 220, - '̮' => 220, - '̯' => 220, - '̰' => 220, - '̱' => 220, - '̲' => 220, - '̳' => 220, - '̴' => 1, - '̵' => 1, - '̶' => 1, - '̷' => 1, - '̸' => 1, - '̹' => 220, - '̺' => 220, - '̻' => 220, - '̼' => 220, - '̽' => 230, - '̾' => 230, - '̿' => 230, - '̀' => 230, - '́' => 230, - '͂' => 230, - '̓' => 230, - '̈́' => 230, - 'ͅ' => 240, - '͆' => 230, - '͇' => 220, - '͈' => 220, - '͉' => 220, - '͊' => 230, - '͋' => 230, - '͌' => 230, - '͍' => 220, - '͎' => 220, - '͐' => 230, - '͑' => 230, - '͒' => 230, - '͓' => 220, - '͔' => 220, - '͕' => 220, - '͖' => 220, - '͗' => 230, - '͘' => 232, - '͙' => 220, - '͚' => 220, - '͛' => 230, - '͜' => 233, - '͝' => 234, - '͞' => 234, - '͟' => 233, - '͠' => 234, - '͡' => 234, - '͢' => 233, - 'ͣ' => 230, - 'ͤ' => 230, - 'ͥ' => 230, - 'ͦ' => 230, - 'ͧ' => 230, - 'ͨ' => 230, - 'ͩ' => 230, - 'ͪ' => 230, - 'ͫ' => 230, - 'ͬ' => 230, - 'ͭ' => 230, - 'ͮ' => 230, - 'ͯ' => 230, - '҃' => 230, - '҄' => 230, - '҅' => 230, - '҆' => 230, - '҇' => 230, - '֑' => 220, - '֒' => 230, - '֓' => 230, - '֔' => 230, - '֕' => 230, - '֖' => 220, - '֗' => 230, - '֘' => 230, - '֙' => 230, - '֚' => 222, - '֛' => 220, - '֜' => 230, - '֝' => 230, - '֞' => 230, - '֟' => 230, - '֠' => 230, - '֡' => 230, - '֢' => 220, - '֣' => 220, - '֤' => 220, - '֥' => 220, - '֦' => 220, - '֧' => 220, - '֨' => 230, - '֩' => 230, - '֪' => 220, - '֫' => 230, - '֬' => 230, - '֭' => 222, - '֮' => 228, - '֯' => 230, - 'ְ' => 10, - 'ֱ' => 11, - 'ֲ' => 12, - 'ֳ' => 13, - 'ִ' => 14, - 'ֵ' => 15, - 'ֶ' => 16, - 'ַ' => 17, - 'ָ' => 18, - 'ֹ' => 19, - 'ֺ' => 19, - 'ֻ' => 20, - 'ּ' => 21, - 'ֽ' => 22, - 'ֿ' => 23, - 'ׁ' => 24, - 'ׂ' => 25, - 'ׄ' => 230, - 'ׅ' => 220, - 'ׇ' => 18, - 'ؐ' => 230, - 'ؑ' => 230, - 'ؒ' => 230, - 'ؓ' => 230, - 'ؔ' => 230, - 'ؕ' => 230, - 'ؖ' => 230, - 'ؗ' => 230, - 'ؘ' => 30, - 'ؙ' => 31, - 'ؚ' => 32, - 'ً' => 27, - 'ٌ' => 28, - 'ٍ' => 29, - 'َ' => 30, - 'ُ' => 31, - 'ِ' => 32, - 'ّ' => 33, - 'ْ' => 34, - 'ٓ' => 230, - 'ٔ' => 230, - 'ٕ' => 220, - 'ٖ' => 220, - 'ٗ' => 230, - '٘' => 230, - 'ٙ' => 230, - 'ٚ' => 230, - 'ٛ' => 230, - 'ٜ' => 220, - 'ٝ' => 230, - 'ٞ' => 230, - 'ٟ' => 220, - 'ٰ' => 35, - 'ۖ' => 230, - 'ۗ' => 230, - 'ۘ' => 230, - 'ۙ' => 230, - 'ۚ' => 230, - 'ۛ' => 230, - 'ۜ' => 230, - '۟' => 230, - '۠' => 230, - 'ۡ' => 230, - 'ۢ' => 230, - 'ۣ' => 220, - 'ۤ' => 230, - 'ۧ' => 230, - 'ۨ' => 230, - '۪' => 220, - '۫' => 230, - '۬' => 230, - 'ۭ' => 220, - 'ܑ' => 36, - 'ܰ' => 230, - 'ܱ' => 220, - 'ܲ' => 230, - 'ܳ' => 230, - 'ܴ' => 220, - 'ܵ' => 230, - 'ܶ' => 230, - 'ܷ' => 220, - 'ܸ' => 220, - 'ܹ' => 220, - 'ܺ' => 230, - 'ܻ' => 220, - 'ܼ' => 220, - 'ܽ' => 230, - 'ܾ' => 220, - 'ܿ' => 230, - '݀' => 230, - '݁' => 230, - '݂' => 220, - '݃' => 230, - '݄' => 220, - '݅' => 230, - '݆' => 220, - '݇' => 230, - '݈' => 220, - '݉' => 230, - '݊' => 230, - '߫' => 230, - '߬' => 230, - '߭' => 230, - '߮' => 230, - '߯' => 230, - '߰' => 230, - '߱' => 230, - '߲' => 220, - '߳' => 230, - '߽' => 220, - 'ࠖ' => 230, - 'ࠗ' => 230, - '࠘' => 230, - '࠙' => 230, - 'ࠛ' => 230, - 'ࠜ' => 230, - 'ࠝ' => 230, - 'ࠞ' => 230, - 'ࠟ' => 230, - 'ࠠ' => 230, - 'ࠡ' => 230, - 'ࠢ' => 230, - 'ࠣ' => 230, - 'ࠥ' => 230, - 'ࠦ' => 230, - 'ࠧ' => 230, - 'ࠩ' => 230, - 'ࠪ' => 230, - 'ࠫ' => 230, - 'ࠬ' => 230, - '࠭' => 230, - '࡙' => 220, - '࡚' => 220, - '࡛' => 220, - '࣓' => 220, - 'ࣔ' => 230, - 'ࣕ' => 230, - 'ࣖ' => 230, - 'ࣗ' => 230, - 'ࣘ' => 230, - 'ࣙ' => 230, - 'ࣚ' => 230, - 'ࣛ' => 230, - 'ࣜ' => 230, - 'ࣝ' => 230, - 'ࣞ' => 230, - 'ࣟ' => 230, - '࣠' => 230, - '࣡' => 230, - 'ࣣ' => 220, - 'ࣤ' => 230, - 'ࣥ' => 230, - 'ࣦ' => 220, - 'ࣧ' => 230, - 'ࣨ' => 230, - 'ࣩ' => 220, - '࣪' => 230, - '࣫' => 230, - '࣬' => 230, - '࣭' => 220, - '࣮' => 220, - '࣯' => 220, - 'ࣰ' => 27, - 'ࣱ' => 28, - 'ࣲ' => 29, - 'ࣳ' => 230, - 'ࣴ' => 230, - 'ࣵ' => 230, - 'ࣶ' => 220, - 'ࣷ' => 230, - 'ࣸ' => 230, - 'ࣹ' => 220, - 'ࣺ' => 220, - 'ࣻ' => 230, - 'ࣼ' => 230, - 'ࣽ' => 230, - 'ࣾ' => 230, - 'ࣿ' => 230, - '़' => 7, - '्' => 9, - '॑' => 230, - '॒' => 220, - '॓' => 230, - '॔' => 230, - '়' => 7, - '্' => 9, - '৾' => 230, - '਼' => 7, - '੍' => 9, - '઼' => 7, - '્' => 9, - '଼' => 7, - '୍' => 9, - '்' => 9, - '్' => 9, - 'ౕ' => 84, - 'ౖ' => 91, - '಼' => 7, - '್' => 9, - '഻' => 9, - '഼' => 9, - '്' => 9, - '්' => 9, - 'ุ' => 103, - 'ู' => 103, - 'ฺ' => 9, - '่' => 107, - '้' => 107, - '๊' => 107, - '๋' => 107, - 'ຸ' => 118, - 'ູ' => 118, - '຺' => 9, - '່' => 122, - '້' => 122, - '໊' => 122, - '໋' => 122, - '༘' => 220, - '༙' => 220, - '༵' => 220, - '༷' => 220, - '༹' => 216, - 'ཱ' => 129, - 'ི' => 130, - 'ུ' => 132, - 'ེ' => 130, - 'ཻ' => 130, - 'ོ' => 130, - 'ཽ' => 130, - 'ྀ' => 130, - 'ྂ' => 230, - 'ྃ' => 230, - '྄' => 9, - '྆' => 230, - '྇' => 230, - '࿆' => 220, - '့' => 7, - '္' => 9, - '်' => 9, - 'ႍ' => 220, - '፝' => 230, - '፞' => 230, - '፟' => 230, - '᜔' => 9, - '᜴' => 9, - '្' => 9, - '៝' => 230, - 'ᢩ' => 228, - '᤹' => 222, - '᤺' => 230, - '᤻' => 220, - 'ᨗ' => 230, - 'ᨘ' => 220, - '᩠' => 9, - '᩵' => 230, - '᩶' => 230, - '᩷' => 230, - '᩸' => 230, - '᩹' => 230, - '᩺' => 230, - '᩻' => 230, - '᩼' => 230, - '᩿' => 220, - '᪰' => 230, - '᪱' => 230, - '᪲' => 230, - '᪳' => 230, - '᪴' => 230, - '᪵' => 220, - '᪶' => 220, - '᪷' => 220, - '᪸' => 220, - '᪹' => 220, - '᪺' => 220, - '᪻' => 230, - '᪼' => 230, - '᪽' => 220, - 'ᪿ' => 220, - 'ᫀ' => 220, - '᬴' => 7, - '᭄' => 9, - '᭫' => 230, - '᭬' => 220, - '᭭' => 230, - '᭮' => 230, - '᭯' => 230, - '᭰' => 230, - '᭱' => 230, - '᭲' => 230, - '᭳' => 230, - '᮪' => 9, - '᮫' => 9, - '᯦' => 7, - '᯲' => 9, - '᯳' => 9, - '᰷' => 7, - '᳐' => 230, - '᳑' => 230, - '᳒' => 230, - '᳔' => 1, - '᳕' => 220, - '᳖' => 220, - '᳗' => 220, - '᳘' => 220, - '᳙' => 220, - '᳚' => 230, - '᳛' => 230, - '᳜' => 220, - '᳝' => 220, - '᳞' => 220, - '᳟' => 220, - '᳠' => 230, - '᳢' => 1, - '᳣' => 1, - '᳤' => 1, - '᳥' => 1, - '᳦' => 1, - '᳧' => 1, - '᳨' => 1, - '᳭' => 220, - '᳴' => 230, - '᳸' => 230, - '᳹' => 230, - '᷀' => 230, - '᷁' => 230, - '᷂' => 220, - '᷃' => 230, - '᷄' => 230, - '᷅' => 230, - '᷆' => 230, - '᷇' => 230, - '᷈' => 230, - '᷉' => 230, - '᷊' => 220, - '᷋' => 230, - '᷌' => 230, - '᷍' => 234, - '᷎' => 214, - '᷏' => 220, - '᷐' => 202, - '᷑' => 230, - '᷒' => 230, - 'ᷓ' => 230, - 'ᷔ' => 230, - 'ᷕ' => 230, - 'ᷖ' => 230, - 'ᷗ' => 230, - 'ᷘ' => 230, - 'ᷙ' => 230, - 'ᷚ' => 230, - 'ᷛ' => 230, - 'ᷜ' => 230, - 'ᷝ' => 230, - 'ᷞ' => 230, - 'ᷟ' => 230, - 'ᷠ' => 230, - 'ᷡ' => 230, - 'ᷢ' => 230, - 'ᷣ' => 230, - 'ᷤ' => 230, - 'ᷥ' => 230, - 'ᷦ' => 230, - 'ᷧ' => 230, - 'ᷨ' => 230, - 'ᷩ' => 230, - 'ᷪ' => 230, - 'ᷫ' => 230, - 'ᷬ' => 230, - 'ᷭ' => 230, - 'ᷮ' => 230, - 'ᷯ' => 230, - 'ᷰ' => 230, - 'ᷱ' => 230, - 'ᷲ' => 230, - 'ᷳ' => 230, - 'ᷴ' => 230, - '᷵' => 230, - '᷶' => 232, - '᷷' => 228, - '᷸' => 228, - '᷹' => 220, - '᷻' => 230, - '᷼' => 233, - '᷽' => 220, - '᷾' => 230, - '᷿' => 220, - '⃐' => 230, - '⃑' => 230, - '⃒' => 1, - '⃓' => 1, - '⃔' => 230, - '⃕' => 230, - '⃖' => 230, - '⃗' => 230, - '⃘' => 1, - '⃙' => 1, - '⃚' => 1, - '⃛' => 230, - '⃜' => 230, - '⃡' => 230, - '⃥' => 1, - '⃦' => 1, - '⃧' => 230, - '⃨' => 220, - '⃩' => 230, - '⃪' => 1, - '⃫' => 1, - '⃬' => 220, - '⃭' => 220, - '⃮' => 220, - '⃯' => 220, - '⃰' => 230, - '⳯' => 230, - '⳰' => 230, - '⳱' => 230, - '⵿' => 9, - 'ⷠ' => 230, - 'ⷡ' => 230, - 'ⷢ' => 230, - 'ⷣ' => 230, - 'ⷤ' => 230, - 'ⷥ' => 230, - 'ⷦ' => 230, - 'ⷧ' => 230, - 'ⷨ' => 230, - 'ⷩ' => 230, - 'ⷪ' => 230, - 'ⷫ' => 230, - 'ⷬ' => 230, - 'ⷭ' => 230, - 'ⷮ' => 230, - 'ⷯ' => 230, - 'ⷰ' => 230, - 'ⷱ' => 230, - 'ⷲ' => 230, - 'ⷳ' => 230, - 'ⷴ' => 230, - 'ⷵ' => 230, - 'ⷶ' => 230, - 'ⷷ' => 230, - 'ⷸ' => 230, - 'ⷹ' => 230, - 'ⷺ' => 230, - 'ⷻ' => 230, - 'ⷼ' => 230, - 'ⷽ' => 230, - 'ⷾ' => 230, - 'ⷿ' => 230, - '〪' => 218, - '〫' => 228, - '〬' => 232, - '〭' => 222, - '〮' => 224, - '〯' => 224, - '゙' => 8, - '゚' => 8, - '꙯' => 230, - 'ꙴ' => 230, - 'ꙵ' => 230, - 'ꙶ' => 230, - 'ꙷ' => 230, - 'ꙸ' => 230, - 'ꙹ' => 230, - 'ꙺ' => 230, - 'ꙻ' => 230, - '꙼' => 230, - '꙽' => 230, - 'ꚞ' => 230, - 'ꚟ' => 230, - '꛰' => 230, - '꛱' => 230, - '꠆' => 9, - '꠬' => 9, - '꣄' => 9, - '꣠' => 230, - '꣡' => 230, - '꣢' => 230, - '꣣' => 230, - '꣤' => 230, - '꣥' => 230, - '꣦' => 230, - '꣧' => 230, - '꣨' => 230, - '꣩' => 230, - '꣪' => 230, - '꣫' => 230, - '꣬' => 230, - '꣭' => 230, - '꣮' => 230, - '꣯' => 230, - '꣰' => 230, - '꣱' => 230, - '꤫' => 220, - '꤬' => 220, - '꤭' => 220, - '꥓' => 9, - '꦳' => 7, - '꧀' => 9, - 'ꪰ' => 230, - 'ꪲ' => 230, - 'ꪳ' => 230, - 'ꪴ' => 220, - 'ꪷ' => 230, - 'ꪸ' => 230, - 'ꪾ' => 230, - '꪿' => 230, - '꫁' => 230, - '꫶' => 9, - '꯭' => 9, - 'ﬞ' => 26, - '︠' => 230, - '︡' => 230, - '︢' => 230, - '︣' => 230, - '︤' => 230, - '︥' => 230, - '︦' => 230, - '︧' => 220, - '︨' => 220, - '︩' => 220, - '︪' => 220, - '︫' => 220, - '︬' => 220, - '︭' => 220, - '︮' => 230, - '︯' => 230, - '𐇽' => 220, - '𐋠' => 220, - '𐍶' => 230, - '𐍷' => 230, - '𐍸' => 230, - '𐍹' => 230, - '𐍺' => 230, - '𐨍' => 220, - '𐨏' => 230, - '𐨸' => 230, - '𐨹' => 1, - '𐨺' => 220, - '𐨿' => 9, - '𐫥' => 230, - '𐫦' => 220, - '𐴤' => 230, - '𐴥' => 230, - '𐴦' => 230, - '𐴧' => 230, - '𐺫' => 230, - '𐺬' => 230, - '𐽆' => 220, - '𐽇' => 220, - '𐽈' => 230, - '𐽉' => 230, - '𐽊' => 230, - '𐽋' => 220, - '𐽌' => 230, - '𐽍' => 220, - '𐽎' => 220, - '𐽏' => 220, - '𐽐' => 220, - '𑁆' => 9, - '𑁿' => 9, - '𑂹' => 9, - '𑂺' => 7, - '𑄀' => 230, - '𑄁' => 230, - '𑄂' => 230, - '𑄳' => 9, - '𑄴' => 9, - '𑅳' => 7, - '𑇀' => 9, - '𑇊' => 7, - '𑈵' => 9, - '𑈶' => 7, - '𑋩' => 7, - '𑋪' => 9, - '𑌻' => 7, - '𑌼' => 7, - '𑍍' => 9, - '𑍦' => 230, - '𑍧' => 230, - '𑍨' => 230, - '𑍩' => 230, - '𑍪' => 230, - '𑍫' => 230, - '𑍬' => 230, - '𑍰' => 230, - '𑍱' => 230, - '𑍲' => 230, - '𑍳' => 230, - '𑍴' => 230, - '𑑂' => 9, - '𑑆' => 7, - '𑑞' => 230, - '𑓂' => 9, - '𑓃' => 7, - '𑖿' => 9, - '𑗀' => 7, - '𑘿' => 9, - '𑚶' => 9, - '𑚷' => 7, - '𑜫' => 9, - '𑠹' => 9, - '𑠺' => 7, - '𑤽' => 9, - '𑤾' => 9, - '𑥃' => 7, - '𑧠' => 9, - '𑨴' => 9, - '𑩇' => 9, - '𑪙' => 9, - '𑰿' => 9, - '𑵂' => 7, - '𑵄' => 9, - '𑵅' => 9, - '𑶗' => 9, - '𖫰' => 1, - '𖫱' => 1, - '𖫲' => 1, - '𖫳' => 1, - '𖫴' => 1, - '𖬰' => 230, - '𖬱' => 230, - '𖬲' => 230, - '𖬳' => 230, - '𖬴' => 230, - '𖬵' => 230, - '𖬶' => 230, - '𖿰' => 6, - '𖿱' => 6, - '𛲞' => 1, - '𝅥' => 216, - '𝅦' => 216, - '𝅧' => 1, - '𝅨' => 1, - '𝅩' => 1, - '𝅭' => 226, - '𝅮' => 216, - '𝅯' => 216, - '𝅰' => 216, - '𝅱' => 216, - '𝅲' => 216, - '𝅻' => 220, - '𝅼' => 220, - '𝅽' => 220, - '𝅾' => 220, - '𝅿' => 220, - '𝆀' => 220, - '𝆁' => 220, - '𝆂' => 220, - '𝆅' => 230, - '𝆆' => 230, - '𝆇' => 230, - '𝆈' => 230, - '𝆉' => 230, - '𝆊' => 220, - '𝆋' => 220, - '𝆪' => 230, - '𝆫' => 230, - '𝆬' => 230, - '𝆭' => 230, - '𝉂' => 230, - '𝉃' => 230, - '𝉄' => 230, - '𞀀' => 230, - '𞀁' => 230, - '𞀂' => 230, - '𞀃' => 230, - '𞀄' => 230, - '𞀅' => 230, - '𞀆' => 230, - '𞀈' => 230, - '𞀉' => 230, - '𞀊' => 230, - '𞀋' => 230, - '𞀌' => 230, - '𞀍' => 230, - '𞀎' => 230, - '𞀏' => 230, - '𞀐' => 230, - '𞀑' => 230, - '𞀒' => 230, - '𞀓' => 230, - '𞀔' => 230, - '𞀕' => 230, - '𞀖' => 230, - '𞀗' => 230, - '𞀘' => 230, - '𞀛' => 230, - '𞀜' => 230, - '𞀝' => 230, - '𞀞' => 230, - '𞀟' => 230, - '𞀠' => 230, - '𞀡' => 230, - '𞀣' => 230, - '𞀤' => 230, - '𞀦' => 230, - '𞀧' => 230, - '𞀨' => 230, - '𞀩' => 230, - '𞀪' => 230, - '𞄰' => 230, - '𞄱' => 230, - '𞄲' => 230, - '𞄳' => 230, - '𞄴' => 230, - '𞄵' => 230, - '𞄶' => 230, - '𞋬' => 230, - '𞋭' => 230, - '𞋮' => 230, - '𞋯' => 230, - '𞣐' => 220, - '𞣑' => 220, - '𞣒' => 220, - '𞣓' => 220, - '𞣔' => 220, - '𞣕' => 220, - '𞣖' => 220, - '𞥄' => 230, - '𞥅' => 230, - '𞥆' => 230, - '𞥇' => 230, - '𞥈' => 230, - '𞥉' => 230, - '𞥊' => 7, -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php deleted file mode 100644 index 157490289..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php +++ /dev/null @@ -1,3695 +0,0 @@ - ' ', - '¨' => ' ̈', - 'ª' => 'a', - '¯' => ' ̄', - '²' => '2', - '³' => '3', - '´' => ' ́', - 'µ' => 'μ', - '¸' => ' ̧', - '¹' => '1', - 'º' => 'o', - '¼' => '1⁄4', - '½' => '1⁄2', - '¾' => '3⁄4', - 'IJ' => 'IJ', - 'ij' => 'ij', - 'Ŀ' => 'L·', - 'ŀ' => 'l·', - 'ʼn' => 'ʼn', - 'ſ' => 's', - 'DŽ' => 'DŽ', - 'Dž' => 'Dž', - 'dž' => 'dž', - 'LJ' => 'LJ', - 'Lj' => 'Lj', - 'lj' => 'lj', - 'NJ' => 'NJ', - 'Nj' => 'Nj', - 'nj' => 'nj', - 'DZ' => 'DZ', - 'Dz' => 'Dz', - 'dz' => 'dz', - 'ʰ' => 'h', - 'ʱ' => 'ɦ', - 'ʲ' => 'j', - 'ʳ' => 'r', - 'ʴ' => 'ɹ', - 'ʵ' => 'ɻ', - 'ʶ' => 'ʁ', - 'ʷ' => 'w', - 'ʸ' => 'y', - '˘' => ' ̆', - '˙' => ' ̇', - '˚' => ' ̊', - '˛' => ' ̨', - '˜' => ' ̃', - '˝' => ' ̋', - 'ˠ' => 'ɣ', - 'ˡ' => 'l', - 'ˢ' => 's', - 'ˣ' => 'x', - 'ˤ' => 'ʕ', - 'ͺ' => ' ͅ', - '΄' => ' ́', - '΅' => ' ̈́', - 'ϐ' => 'β', - 'ϑ' => 'θ', - 'ϒ' => 'Υ', - 'ϓ' => 'Ύ', - 'ϔ' => 'Ϋ', - 'ϕ' => 'φ', - 'ϖ' => 'π', - 'ϰ' => 'κ', - 'ϱ' => 'ρ', - 'ϲ' => 'ς', - 'ϴ' => 'Θ', - 'ϵ' => 'ε', - 'Ϲ' => 'Σ', - 'և' => 'եւ', - 'ٵ' => 'اٴ', - 'ٶ' => 'وٴ', - 'ٷ' => 'ۇٴ', - 'ٸ' => 'يٴ', - 'ำ' => 'ํา', - 'ຳ' => 'ໍາ', - 'ໜ' => 'ຫນ', - 'ໝ' => 'ຫມ', - '༌' => '་', - 'ཷ' => 'ྲཱྀ', - 'ཹ' => 'ླཱྀ', - 'ჼ' => 'ნ', - 'ᴬ' => 'A', - 'ᴭ' => 'Æ', - 'ᴮ' => 'B', - 'ᴰ' => 'D', - 'ᴱ' => 'E', - 'ᴲ' => 'Ǝ', - 'ᴳ' => 'G', - 'ᴴ' => 'H', - 'ᴵ' => 'I', - 'ᴶ' => 'J', - 'ᴷ' => 'K', - 'ᴸ' => 'L', - 'ᴹ' => 'M', - 'ᴺ' => 'N', - 'ᴼ' => 'O', - 'ᴽ' => 'Ȣ', - 'ᴾ' => 'P', - 'ᴿ' => 'R', - 'ᵀ' => 'T', - 'ᵁ' => 'U', - 'ᵂ' => 'W', - 'ᵃ' => 'a', - 'ᵄ' => 'ɐ', - 'ᵅ' => 'ɑ', - 'ᵆ' => 'ᴂ', - 'ᵇ' => 'b', - 'ᵈ' => 'd', - 'ᵉ' => 'e', - 'ᵊ' => 'ə', - 'ᵋ' => 'ɛ', - 'ᵌ' => 'ɜ', - 'ᵍ' => 'g', - 'ᵏ' => 'k', - 'ᵐ' => 'm', - 'ᵑ' => 'ŋ', - 'ᵒ' => 'o', - 'ᵓ' => 'ɔ', - 'ᵔ' => 'ᴖ', - 'ᵕ' => 'ᴗ', - 'ᵖ' => 'p', - 'ᵗ' => 't', - 'ᵘ' => 'u', - 'ᵙ' => 'ᴝ', - 'ᵚ' => 'ɯ', - 'ᵛ' => 'v', - 'ᵜ' => 'ᴥ', - 'ᵝ' => 'β', - 'ᵞ' => 'γ', - 'ᵟ' => 'δ', - 'ᵠ' => 'φ', - 'ᵡ' => 'χ', - 'ᵢ' => 'i', - 'ᵣ' => 'r', - 'ᵤ' => 'u', - 'ᵥ' => 'v', - 'ᵦ' => 'β', - 'ᵧ' => 'γ', - 'ᵨ' => 'ρ', - 'ᵩ' => 'φ', - 'ᵪ' => 'χ', - 'ᵸ' => 'н', - 'ᶛ' => 'ɒ', - 'ᶜ' => 'c', - 'ᶝ' => 'ɕ', - 'ᶞ' => 'ð', - 'ᶟ' => 'ɜ', - 'ᶠ' => 'f', - 'ᶡ' => 'ɟ', - 'ᶢ' => 'ɡ', - 'ᶣ' => 'ɥ', - 'ᶤ' => 'ɨ', - 'ᶥ' => 'ɩ', - 'ᶦ' => 'ɪ', - 'ᶧ' => 'ᵻ', - 'ᶨ' => 'ʝ', - 'ᶩ' => 'ɭ', - 'ᶪ' => 'ᶅ', - 'ᶫ' => 'ʟ', - 'ᶬ' => 'ɱ', - 'ᶭ' => 'ɰ', - 'ᶮ' => 'ɲ', - 'ᶯ' => 'ɳ', - 'ᶰ' => 'ɴ', - 'ᶱ' => 'ɵ', - 'ᶲ' => 'ɸ', - 'ᶳ' => 'ʂ', - 'ᶴ' => 'ʃ', - 'ᶵ' => 'ƫ', - 'ᶶ' => 'ʉ', - 'ᶷ' => 'ʊ', - 'ᶸ' => 'ᴜ', - 'ᶹ' => 'ʋ', - 'ᶺ' => 'ʌ', - 'ᶻ' => 'z', - 'ᶼ' => 'ʐ', - 'ᶽ' => 'ʑ', - 'ᶾ' => 'ʒ', - 'ᶿ' => 'θ', - 'ẚ' => 'aʾ', - 'ẛ' => 'ṡ', - '᾽' => ' ̓', - '᾿' => ' ̓', - '῀' => ' ͂', - '῁' => ' ̈͂', - '῍' => ' ̓̀', - '῎' => ' ̓́', - '῏' => ' ̓͂', - '῝' => ' ̔̀', - '῞' => ' ̔́', - '῟' => ' ̔͂', - '῭' => ' ̈̀', - '΅' => ' ̈́', - '´' => ' ́', - '῾' => ' ̔', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - '‑' => '‐', - '‗' => ' ̳', - '․' => '.', - '‥' => '..', - '…' => '...', - ' ' => ' ', - '″' => '′′', - '‴' => '′′′', - '‶' => '‵‵', - '‷' => '‵‵‵', - '‼' => '!!', - '‾' => ' ̅', - '⁇' => '??', - '⁈' => '?!', - '⁉' => '!?', - '⁗' => '′′′′', - ' ' => ' ', - '⁰' => '0', - 'ⁱ' => 'i', - '⁴' => '4', - '⁵' => '5', - '⁶' => '6', - '⁷' => '7', - '⁸' => '8', - '⁹' => '9', - '⁺' => '+', - '⁻' => '−', - '⁼' => '=', - '⁽' => '(', - '⁾' => ')', - 'ⁿ' => 'n', - '₀' => '0', - '₁' => '1', - '₂' => '2', - '₃' => '3', - '₄' => '4', - '₅' => '5', - '₆' => '6', - '₇' => '7', - '₈' => '8', - '₉' => '9', - '₊' => '+', - '₋' => '−', - '₌' => '=', - '₍' => '(', - '₎' => ')', - 'ₐ' => 'a', - 'ₑ' => 'e', - 'ₒ' => 'o', - 'ₓ' => 'x', - 'ₔ' => 'ə', - 'ₕ' => 'h', - 'ₖ' => 'k', - 'ₗ' => 'l', - 'ₘ' => 'm', - 'ₙ' => 'n', - 'ₚ' => 'p', - 'ₛ' => 's', - 'ₜ' => 't', - '₨' => 'Rs', - '℀' => 'a/c', - '℁' => 'a/s', - 'ℂ' => 'C', - '℃' => '°C', - '℅' => 'c/o', - '℆' => 'c/u', - 'ℇ' => 'Ɛ', - '℉' => '°F', - 'ℊ' => 'g', - 'ℋ' => 'H', - 'ℌ' => 'H', - 'ℍ' => 'H', - 'ℎ' => 'h', - 'ℏ' => 'ħ', - 'ℐ' => 'I', - 'ℑ' => 'I', - 'ℒ' => 'L', - 'ℓ' => 'l', - 'ℕ' => 'N', - '№' => 'No', - 'ℙ' => 'P', - 'ℚ' => 'Q', - 'ℛ' => 'R', - 'ℜ' => 'R', - 'ℝ' => 'R', - '℠' => 'SM', - '℡' => 'TEL', - '™' => 'TM', - 'ℤ' => 'Z', - 'ℨ' => 'Z', - 'ℬ' => 'B', - 'ℭ' => 'C', - 'ℯ' => 'e', - 'ℰ' => 'E', - 'ℱ' => 'F', - 'ℳ' => 'M', - 'ℴ' => 'o', - 'ℵ' => 'א', - 'ℶ' => 'ב', - 'ℷ' => 'ג', - 'ℸ' => 'ד', - 'ℹ' => 'i', - '℻' => 'FAX', - 'ℼ' => 'π', - 'ℽ' => 'γ', - 'ℾ' => 'Γ', - 'ℿ' => 'Π', - '⅀' => '∑', - 'ⅅ' => 'D', - 'ⅆ' => 'd', - 'ⅇ' => 'e', - 'ⅈ' => 'i', - 'ⅉ' => 'j', - '⅐' => '1⁄7', - '⅑' => '1⁄9', - '⅒' => '1⁄10', - '⅓' => '1⁄3', - '⅔' => '2⁄3', - '⅕' => '1⁄5', - '⅖' => '2⁄5', - '⅗' => '3⁄5', - '⅘' => '4⁄5', - '⅙' => '1⁄6', - '⅚' => '5⁄6', - '⅛' => '1⁄8', - '⅜' => '3⁄8', - '⅝' => '5⁄8', - '⅞' => '7⁄8', - '⅟' => '1⁄', - 'Ⅰ' => 'I', - 'Ⅱ' => 'II', - 'Ⅲ' => 'III', - 'Ⅳ' => 'IV', - 'Ⅴ' => 'V', - 'Ⅵ' => 'VI', - 'Ⅶ' => 'VII', - 'Ⅷ' => 'VIII', - 'Ⅸ' => 'IX', - 'Ⅹ' => 'X', - 'Ⅺ' => 'XI', - 'Ⅻ' => 'XII', - 'Ⅼ' => 'L', - 'Ⅽ' => 'C', - 'Ⅾ' => 'D', - 'Ⅿ' => 'M', - 'ⅰ' => 'i', - 'ⅱ' => 'ii', - 'ⅲ' => 'iii', - 'ⅳ' => 'iv', - 'ⅴ' => 'v', - 'ⅵ' => 'vi', - 'ⅶ' => 'vii', - 'ⅷ' => 'viii', - 'ⅸ' => 'ix', - 'ⅹ' => 'x', - 'ⅺ' => 'xi', - 'ⅻ' => 'xii', - 'ⅼ' => 'l', - 'ⅽ' => 'c', - 'ⅾ' => 'd', - 'ⅿ' => 'm', - '↉' => '0⁄3', - '∬' => '∫∫', - '∭' => '∫∫∫', - '∯' => '∮∮', - '∰' => '∮∮∮', - '①' => '1', - '②' => '2', - '③' => '3', - '④' => '4', - '⑤' => '5', - '⑥' => '6', - '⑦' => '7', - '⑧' => '8', - '⑨' => '9', - '⑩' => '10', - '⑪' => '11', - '⑫' => '12', - '⑬' => '13', - '⑭' => '14', - '⑮' => '15', - '⑯' => '16', - '⑰' => '17', - '⑱' => '18', - '⑲' => '19', - '⑳' => '20', - '⑴' => '(1)', - '⑵' => '(2)', - '⑶' => '(3)', - '⑷' => '(4)', - '⑸' => '(5)', - '⑹' => '(6)', - '⑺' => '(7)', - '⑻' => '(8)', - '⑼' => '(9)', - '⑽' => '(10)', - '⑾' => '(11)', - '⑿' => '(12)', - '⒀' => '(13)', - '⒁' => '(14)', - '⒂' => '(15)', - '⒃' => '(16)', - '⒄' => '(17)', - '⒅' => '(18)', - '⒆' => '(19)', - '⒇' => '(20)', - '⒈' => '1.', - '⒉' => '2.', - '⒊' => '3.', - '⒋' => '4.', - '⒌' => '5.', - '⒍' => '6.', - '⒎' => '7.', - '⒏' => '8.', - '⒐' => '9.', - '⒑' => '10.', - '⒒' => '11.', - '⒓' => '12.', - '⒔' => '13.', - '⒕' => '14.', - '⒖' => '15.', - '⒗' => '16.', - '⒘' => '17.', - '⒙' => '18.', - '⒚' => '19.', - '⒛' => '20.', - '⒜' => '(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)', - 'Ⓐ' => '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', - 'ⓐ' => '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', - '⓪' => '0', - '⨌' => '∫∫∫∫', - '⩴' => '::=', - '⩵' => '==', - '⩶' => '===', - 'ⱼ' => 'j', - 'ⱽ' => 'V', - 'ⵯ' => 'ⵡ', - '⺟' => '母', - '⻳' => '龟', - '⼀' => '一', - '⼁' => '丨', - '⼂' => '丶', - '⼃' => '丿', - '⼄' => '乙', - '⼅' => '亅', - '⼆' => '二', - '⼇' => '亠', - '⼈' => '人', - '⼉' => '儿', - '⼊' => '入', - '⼋' => '八', - '⼌' => '冂', - '⼍' => '冖', - '⼎' => '冫', - '⼏' => '几', - '⼐' => '凵', - '⼑' => '刀', - '⼒' => '力', - '⼓' => '勹', - '⼔' => '匕', - '⼕' => '匚', - '⼖' => '匸', - '⼗' => '十', - '⼘' => '卜', - '⼙' => '卩', - '⼚' => '厂', - '⼛' => '厶', - '⼜' => '又', - '⼝' => '口', - '⼞' => '囗', - '⼟' => '土', - '⼠' => '士', - '⼡' => '夂', - '⼢' => '夊', - '⼣' => '夕', - '⼤' => '大', - '⼥' => '女', - '⼦' => '子', - '⼧' => '宀', - '⼨' => '寸', - '⼩' => '小', - '⼪' => '尢', - '⼫' => '尸', - '⼬' => '屮', - '⼭' => '山', - '⼮' => '巛', - '⼯' => '工', - '⼰' => '己', - '⼱' => '巾', - '⼲' => '干', - '⼳' => '幺', - '⼴' => '广', - '⼵' => '廴', - '⼶' => '廾', - '⼷' => '弋', - '⼸' => '弓', - '⼹' => '彐', - '⼺' => '彡', - '⼻' => '彳', - '⼼' => '心', - '⼽' => '戈', - '⼾' => '戶', - '⼿' => '手', - '⽀' => '支', - '⽁' => '攴', - '⽂' => '文', - '⽃' => '斗', - '⽄' => '斤', - '⽅' => '方', - '⽆' => '无', - '⽇' => '日', - '⽈' => '曰', - '⽉' => '月', - '⽊' => '木', - '⽋' => '欠', - '⽌' => '止', - '⽍' => '歹', - '⽎' => '殳', - '⽏' => '毋', - '⽐' => '比', - '⽑' => '毛', - '⽒' => '氏', - '⽓' => '气', - '⽔' => '水', - '⽕' => '火', - '⽖' => '爪', - '⽗' => '父', - '⽘' => '爻', - '⽙' => '爿', - '⽚' => '片', - '⽛' => '牙', - '⽜' => '牛', - '⽝' => '犬', - '⽞' => '玄', - '⽟' => '玉', - '⽠' => '瓜', - '⽡' => '瓦', - '⽢' => '甘', - '⽣' => '生', - '⽤' => '用', - '⽥' => '田', - '⽦' => '疋', - '⽧' => '疒', - '⽨' => '癶', - '⽩' => '白', - '⽪' => '皮', - '⽫' => '皿', - '⽬' => '目', - '⽭' => '矛', - '⽮' => '矢', - '⽯' => '石', - '⽰' => '示', - '⽱' => '禸', - '⽲' => '禾', - '⽳' => '穴', - '⽴' => '立', - '⽵' => '竹', - '⽶' => '米', - '⽷' => '糸', - '⽸' => '缶', - '⽹' => '网', - '⽺' => '羊', - '⽻' => '羽', - '⽼' => '老', - '⽽' => '而', - '⽾' => '耒', - '⽿' => '耳', - '⾀' => '聿', - '⾁' => '肉', - '⾂' => '臣', - '⾃' => '自', - '⾄' => '至', - '⾅' => '臼', - '⾆' => '舌', - '⾇' => '舛', - '⾈' => '舟', - '⾉' => '艮', - '⾊' => '色', - '⾋' => '艸', - '⾌' => '虍', - '⾍' => '虫', - '⾎' => '血', - '⾏' => '行', - '⾐' => '衣', - '⾑' => '襾', - '⾒' => '見', - '⾓' => '角', - '⾔' => '言', - '⾕' => '谷', - '⾖' => '豆', - '⾗' => '豕', - '⾘' => '豸', - '⾙' => '貝', - '⾚' => '赤', - '⾛' => '走', - '⾜' => '足', - '⾝' => '身', - '⾞' => '車', - '⾟' => '辛', - '⾠' => '辰', - '⾡' => '辵', - '⾢' => '邑', - '⾣' => '酉', - '⾤' => '釆', - '⾥' => '里', - '⾦' => '金', - '⾧' => '長', - '⾨' => '門', - '⾩' => '阜', - '⾪' => '隶', - '⾫' => '隹', - '⾬' => '雨', - '⾭' => '靑', - '⾮' => '非', - '⾯' => '面', - '⾰' => '革', - '⾱' => '韋', - '⾲' => '韭', - '⾳' => '音', - '⾴' => '頁', - '⾵' => '風', - '⾶' => '飛', - '⾷' => '食', - '⾸' => '首', - '⾹' => '香', - '⾺' => '馬', - '⾻' => '骨', - '⾼' => '高', - '⾽' => '髟', - '⾾' => '鬥', - '⾿' => '鬯', - '⿀' => '鬲', - '⿁' => '鬼', - '⿂' => '魚', - '⿃' => '鳥', - '⿄' => '鹵', - '⿅' => '鹿', - '⿆' => '麥', - '⿇' => '麻', - '⿈' => '黃', - '⿉' => '黍', - '⿊' => '黑', - '⿋' => '黹', - '⿌' => '黽', - '⿍' => '鼎', - '⿎' => '鼓', - '⿏' => '鼠', - '⿐' => '鼻', - '⿑' => '齊', - '⿒' => '齒', - '⿓' => '龍', - '⿔' => '龜', - '⿕' => '龠', - ' ' => ' ', - '〶' => '〒', - '〸' => '十', - '〹' => '卄', - '〺' => '卅', - '゛' => ' ゙', - '゜' => ' ゚', - 'ゟ' => 'より', - 'ヿ' => 'コト', - 'ㄱ' => 'ᄀ', - 'ㄲ' => 'ᄁ', - 'ㄳ' => 'ᆪ', - 'ㄴ' => 'ᄂ', - 'ㄵ' => 'ᆬ', - 'ㄶ' => 'ᆭ', - 'ㄷ' => 'ᄃ', - 'ㄸ' => 'ᄄ', - 'ㄹ' => 'ᄅ', - 'ㄺ' => 'ᆰ', - 'ㄻ' => 'ᆱ', - 'ㄼ' => 'ᆲ', - 'ㄽ' => 'ᆳ', - 'ㄾ' => 'ᆴ', - 'ㄿ' => 'ᆵ', - 'ㅀ' => 'ᄚ', - 'ㅁ' => 'ᄆ', - 'ㅂ' => 'ᄇ', - 'ㅃ' => 'ᄈ', - 'ㅄ' => 'ᄡ', - 'ㅅ' => 'ᄉ', - 'ㅆ' => 'ᄊ', - 'ㅇ' => 'ᄋ', - 'ㅈ' => 'ᄌ', - 'ㅉ' => 'ᄍ', - 'ㅊ' => 'ᄎ', - 'ㅋ' => 'ᄏ', - 'ㅌ' => 'ᄐ', - 'ㅍ' => 'ᄑ', - 'ㅎ' => 'ᄒ', - 'ㅏ' => 'ᅡ', - 'ㅐ' => 'ᅢ', - 'ㅑ' => 'ᅣ', - 'ㅒ' => 'ᅤ', - 'ㅓ' => 'ᅥ', - 'ㅔ' => 'ᅦ', - 'ㅕ' => 'ᅧ', - 'ㅖ' => 'ᅨ', - 'ㅗ' => 'ᅩ', - 'ㅘ' => 'ᅪ', - 'ㅙ' => 'ᅫ', - 'ㅚ' => 'ᅬ', - 'ㅛ' => 'ᅭ', - 'ㅜ' => 'ᅮ', - 'ㅝ' => 'ᅯ', - 'ㅞ' => 'ᅰ', - 'ㅟ' => 'ᅱ', - 'ㅠ' => 'ᅲ', - 'ㅡ' => 'ᅳ', - 'ㅢ' => 'ᅴ', - 'ㅣ' => 'ᅵ', - 'ㅤ' => 'ᅠ', - 'ㅥ' => 'ᄔ', - 'ㅦ' => 'ᄕ', - 'ㅧ' => 'ᇇ', - 'ㅨ' => 'ᇈ', - 'ㅩ' => 'ᇌ', - 'ㅪ' => 'ᇎ', - 'ㅫ' => 'ᇓ', - 'ㅬ' => 'ᇗ', - 'ㅭ' => 'ᇙ', - 'ㅮ' => 'ᄜ', - 'ㅯ' => 'ᇝ', - 'ㅰ' => 'ᇟ', - 'ㅱ' => 'ᄝ', - 'ㅲ' => 'ᄞ', - 'ㅳ' => 'ᄠ', - 'ㅴ' => 'ᄢ', - 'ㅵ' => 'ᄣ', - 'ㅶ' => 'ᄧ', - 'ㅷ' => 'ᄩ', - 'ㅸ' => 'ᄫ', - 'ㅹ' => 'ᄬ', - 'ㅺ' => 'ᄭ', - 'ㅻ' => 'ᄮ', - 'ㅼ' => 'ᄯ', - 'ㅽ' => 'ᄲ', - 'ㅾ' => 'ᄶ', - 'ㅿ' => 'ᅀ', - 'ㆀ' => 'ᅇ', - 'ㆁ' => 'ᅌ', - 'ㆂ' => 'ᇱ', - 'ㆃ' => 'ᇲ', - 'ㆄ' => 'ᅗ', - 'ㆅ' => 'ᅘ', - 'ㆆ' => 'ᅙ', - 'ㆇ' => 'ᆄ', - 'ㆈ' => 'ᆅ', - 'ㆉ' => 'ᆈ', - 'ㆊ' => 'ᆑ', - 'ㆋ' => 'ᆒ', - 'ㆌ' => 'ᆔ', - 'ㆍ' => 'ᆞ', - 'ㆎ' => 'ᆡ', - '㆒' => '一', - '㆓' => '二', - '㆔' => '三', - '㆕' => '四', - '㆖' => '上', - '㆗' => '中', - '㆘' => '下', - '㆙' => '甲', - '㆚' => '乙', - '㆛' => '丙', - '㆜' => '丁', - '㆝' => '天', - '㆞' => '地', - '㆟' => '人', - '㈀' => '(ᄀ)', - '㈁' => '(ᄂ)', - '㈂' => '(ᄃ)', - '㈃' => '(ᄅ)', - '㈄' => '(ᄆ)', - '㈅' => '(ᄇ)', - '㈆' => '(ᄉ)', - '㈇' => '(ᄋ)', - '㈈' => '(ᄌ)', - '㈉' => '(ᄎ)', - '㈊' => '(ᄏ)', - '㈋' => '(ᄐ)', - '㈌' => '(ᄑ)', - '㈍' => '(ᄒ)', - '㈎' => '(가)', - '㈏' => '(나)', - '㈐' => '(다)', - '㈑' => '(라)', - '㈒' => '(마)', - '㈓' => '(바)', - '㈔' => '(사)', - '㈕' => '(아)', - '㈖' => '(자)', - '㈗' => '(차)', - '㈘' => '(카)', - '㈙' => '(타)', - '㈚' => '(파)', - '㈛' => '(하)', - '㈜' => '(주)', - '㈝' => '(오전)', - '㈞' => '(오후)', - '㈠' => '(一)', - '㈡' => '(二)', - '㈢' => '(三)', - '㈣' => '(四)', - '㈤' => '(五)', - '㈥' => '(六)', - '㈦' => '(七)', - '㈧' => '(八)', - '㈨' => '(九)', - '㈩' => '(十)', - '㈪' => '(月)', - '㈫' => '(火)', - '㈬' => '(水)', - '㈭' => '(木)', - '㈮' => '(金)', - '㈯' => '(土)', - '㈰' => '(日)', - '㈱' => '(株)', - '㈲' => '(有)', - '㈳' => '(社)', - '㈴' => '(名)', - '㈵' => '(特)', - '㈶' => '(財)', - '㈷' => '(祝)', - '㈸' => '(労)', - '㈹' => '(代)', - '㈺' => '(呼)', - '㈻' => '(学)', - '㈼' => '(監)', - '㈽' => '(企)', - '㈾' => '(資)', - '㈿' => '(協)', - '㉀' => '(祭)', - '㉁' => '(休)', - '㉂' => '(自)', - '㉃' => '(至)', - '㉄' => '問', - '㉅' => '幼', - '㉆' => '文', - '㉇' => '箏', - '㉐' => 'PTE', - '㉑' => '21', - '㉒' => '22', - '㉓' => '23', - '㉔' => '24', - '㉕' => '25', - '㉖' => '26', - '㉗' => '27', - '㉘' => '28', - '㉙' => '29', - '㉚' => '30', - '㉛' => '31', - '㉜' => '32', - '㉝' => '33', - '㉞' => '34', - '㉟' => '35', - '㉠' => 'ᄀ', - '㉡' => 'ᄂ', - '㉢' => 'ᄃ', - '㉣' => 'ᄅ', - '㉤' => 'ᄆ', - '㉥' => 'ᄇ', - '㉦' => 'ᄉ', - '㉧' => 'ᄋ', - '㉨' => 'ᄌ', - '㉩' => 'ᄎ', - '㉪' => 'ᄏ', - '㉫' => 'ᄐ', - '㉬' => 'ᄑ', - '㉭' => 'ᄒ', - '㉮' => '가', - '㉯' => '나', - '㉰' => '다', - '㉱' => '라', - '㉲' => '마', - '㉳' => '바', - '㉴' => '사', - '㉵' => '아', - '㉶' => '자', - '㉷' => '차', - '㉸' => '카', - '㉹' => '타', - '㉺' => '파', - '㉻' => '하', - '㉼' => '참고', - '㉽' => '주의', - '㉾' => '우', - '㊀' => '一', - '㊁' => '二', - '㊂' => '三', - '㊃' => '四', - '㊄' => '五', - '㊅' => '六', - '㊆' => '七', - '㊇' => '八', - '㊈' => '九', - '㊉' => '十', - '㊊' => '月', - '㊋' => '火', - '㊌' => '水', - '㊍' => '木', - '㊎' => '金', - '㊏' => '土', - '㊐' => '日', - '㊑' => '株', - '㊒' => '有', - '㊓' => '社', - '㊔' => '名', - '㊕' => '特', - '㊖' => '財', - '㊗' => '祝', - '㊘' => '労', - '㊙' => '秘', - '㊚' => '男', - '㊛' => '女', - '㊜' => '適', - '㊝' => '優', - '㊞' => '印', - '㊟' => '注', - '㊠' => '項', - '㊡' => '休', - '㊢' => '写', - '㊣' => '正', - '㊤' => '上', - '㊥' => '中', - '㊦' => '下', - '㊧' => '左', - '㊨' => '右', - '㊩' => '医', - '㊪' => '宗', - '㊫' => '学', - '㊬' => '監', - '㊭' => '企', - '㊮' => '資', - '㊯' => '協', - '㊰' => '夜', - '㊱' => '36', - '㊲' => '37', - '㊳' => '38', - '㊴' => '39', - '㊵' => '40', - '㊶' => '41', - '㊷' => '42', - '㊸' => '43', - '㊹' => '44', - '㊺' => '45', - '㊻' => '46', - '㊼' => '47', - '㊽' => '48', - '㊾' => '49', - '㊿' => '50', - '㋀' => '1月', - '㋁' => '2月', - '㋂' => '3月', - '㋃' => '4月', - '㋄' => '5月', - '㋅' => '6月', - '㋆' => '7月', - '㋇' => '8月', - '㋈' => '9月', - '㋉' => '10月', - '㋊' => '11月', - '㋋' => '12月', - '㋌' => 'Hg', - '㋍' => 'erg', - '㋎' => 'eV', - '㋏' => 'LTD', - '㋐' => 'ア', - '㋑' => 'イ', - '㋒' => 'ウ', - '㋓' => 'エ', - '㋔' => 'オ', - '㋕' => 'カ', - '㋖' => 'キ', - '㋗' => 'ク', - '㋘' => 'ケ', - '㋙' => 'コ', - '㋚' => 'サ', - '㋛' => 'シ', - '㋜' => 'ス', - '㋝' => 'セ', - '㋞' => 'ソ', - '㋟' => 'タ', - '㋠' => 'チ', - '㋡' => 'ツ', - '㋢' => 'テ', - '㋣' => 'ト', - '㋤' => 'ナ', - '㋥' => 'ニ', - '㋦' => 'ヌ', - '㋧' => 'ネ', - '㋨' => 'ノ', - '㋩' => 'ハ', - '㋪' => 'ヒ', - '㋫' => 'フ', - '㋬' => 'ヘ', - '㋭' => 'ホ', - '㋮' => 'マ', - '㋯' => 'ミ', - '㋰' => 'ム', - '㋱' => 'メ', - '㋲' => 'モ', - '㋳' => 'ヤ', - '㋴' => 'ユ', - '㋵' => 'ヨ', - '㋶' => 'ラ', - '㋷' => 'リ', - '㋸' => 'ル', - '㋹' => 'レ', - '㋺' => 'ロ', - '㋻' => 'ワ', - '㋼' => 'ヰ', - '㋽' => 'ヱ', - '㋾' => 'ヲ', - '㋿' => '令和', - '㌀' => 'アパート', - '㌁' => 'アルファ', - '㌂' => 'アンペア', - '㌃' => 'アール', - '㌄' => 'イニング', - '㌅' => 'インチ', - '㌆' => 'ウォン', - '㌇' => 'エスクード', - '㌈' => 'エーカー', - '㌉' => 'オンス', - '㌊' => 'オーム', - '㌋' => 'カイリ', - '㌌' => 'カラット', - '㌍' => 'カロリー', - '㌎' => 'ガロン', - '㌏' => 'ガンマ', - '㌐' => 'ギガ', - '㌑' => 'ギニー', - '㌒' => 'キュリー', - '㌓' => 'ギルダー', - '㌔' => 'キロ', - '㌕' => 'キログラム', - '㌖' => 'キロメートル', - '㌗' => 'キロワット', - '㌘' => 'グラム', - '㌙' => 'グラムトン', - '㌚' => 'クルゼイロ', - '㌛' => 'クローネ', - '㌜' => 'ケース', - '㌝' => 'コルナ', - '㌞' => 'コーポ', - '㌟' => 'サイクル', - '㌠' => 'サンチーム', - '㌡' => 'シリング', - '㌢' => 'センチ', - '㌣' => 'セント', - '㌤' => 'ダース', - '㌥' => 'デシ', - '㌦' => 'ドル', - '㌧' => 'トン', - '㌨' => 'ナノ', - '㌩' => 'ノット', - '㌪' => 'ハイツ', - '㌫' => 'パーセント', - '㌬' => 'パーツ', - '㌭' => 'バーレル', - '㌮' => 'ピアストル', - '㌯' => 'ピクル', - '㌰' => 'ピコ', - '㌱' => 'ビル', - '㌲' => 'ファラッド', - '㌳' => 'フィート', - '㌴' => 'ブッシェル', - '㌵' => 'フラン', - '㌶' => 'ヘクタール', - '㌷' => 'ペソ', - '㌸' => 'ペニヒ', - '㌹' => 'ヘルツ', - '㌺' => 'ペンス', - '㌻' => 'ページ', - '㌼' => 'ベータ', - '㌽' => 'ポイント', - '㌾' => 'ボルト', - '㌿' => 'ホン', - '㍀' => 'ポンド', - '㍁' => 'ホール', - '㍂' => 'ホーン', - '㍃' => 'マイクロ', - '㍄' => 'マイル', - '㍅' => 'マッハ', - '㍆' => 'マルク', - '㍇' => 'マンション', - '㍈' => 'ミクロン', - '㍉' => 'ミリ', - '㍊' => 'ミリバール', - '㍋' => 'メガ', - '㍌' => 'メガトン', - '㍍' => 'メートル', - '㍎' => 'ヤード', - '㍏' => 'ヤール', - '㍐' => 'ユアン', - '㍑' => 'リットル', - '㍒' => 'リラ', - '㍓' => 'ルピー', - '㍔' => 'ルーブル', - '㍕' => 'レム', - '㍖' => 'レントゲン', - '㍗' => 'ワット', - '㍘' => '0点', - '㍙' => '1点', - '㍚' => '2点', - '㍛' => '3点', - '㍜' => '4点', - '㍝' => '5点', - '㍞' => '6点', - '㍟' => '7点', - '㍠' => '8点', - '㍡' => '9点', - '㍢' => '10点', - '㍣' => '11点', - '㍤' => '12点', - '㍥' => '13点', - '㍦' => '14点', - '㍧' => '15点', - '㍨' => '16点', - '㍩' => '17点', - '㍪' => '18点', - '㍫' => '19点', - '㍬' => '20点', - '㍭' => '21点', - '㍮' => '22点', - '㍯' => '23点', - '㍰' => '24点', - '㍱' => 'hPa', - '㍲' => 'da', - '㍳' => 'AU', - '㍴' => 'bar', - '㍵' => 'oV', - '㍶' => 'pc', - '㍷' => 'dm', - '㍸' => 'dm2', - '㍹' => 'dm3', - '㍺' => 'IU', - '㍻' => '平成', - '㍼' => '昭和', - '㍽' => '大正', - '㍾' => '明治', - '㍿' => '株式会社', - '㎀' => 'pA', - '㎁' => 'nA', - '㎂' => 'μA', - '㎃' => 'mA', - '㎄' => 'kA', - '㎅' => 'KB', - '㎆' => 'MB', - '㎇' => 'GB', - '㎈' => 'cal', - '㎉' => 'kcal', - '㎊' => 'pF', - '㎋' => 'nF', - '㎌' => 'μF', - '㎍' => 'μg', - '㎎' => 'mg', - '㎏' => 'kg', - '㎐' => 'Hz', - '㎑' => 'kHz', - '㎒' => 'MHz', - '㎓' => 'GHz', - '㎔' => 'THz', - '㎕' => 'μl', - '㎖' => 'ml', - '㎗' => 'dl', - '㎘' => 'kl', - '㎙' => 'fm', - '㎚' => 'nm', - '㎛' => 'μm', - '㎜' => 'mm', - '㎝' => 'cm', - '㎞' => 'km', - '㎟' => 'mm2', - '㎠' => 'cm2', - '㎡' => 'm2', - '㎢' => 'km2', - '㎣' => 'mm3', - '㎤' => 'cm3', - '㎥' => 'm3', - '㎦' => 'km3', - '㎧' => 'm∕s', - '㎨' => 'm∕s2', - '㎩' => 'Pa', - '㎪' => 'kPa', - '㎫' => 'MPa', - '㎬' => 'GPa', - '㎭' => 'rad', - '㎮' => 'rad∕s', - '㎯' => 'rad∕s2', - '㎰' => 'ps', - '㎱' => 'ns', - '㎲' => 'μs', - '㎳' => 'ms', - '㎴' => 'pV', - '㎵' => 'nV', - '㎶' => 'μV', - '㎷' => 'mV', - '㎸' => 'kV', - '㎹' => 'MV', - '㎺' => 'pW', - '㎻' => 'nW', - '㎼' => 'μW', - '㎽' => 'mW', - '㎾' => 'kW', - '㎿' => 'MW', - '㏀' => 'kΩ', - '㏁' => 'MΩ', - '㏂' => 'a.m.', - '㏃' => 'Bq', - '㏄' => 'cc', - '㏅' => 'cd', - '㏆' => 'C∕kg', - '㏇' => 'Co.', - '㏈' => 'dB', - '㏉' => 'Gy', - '㏊' => 'ha', - '㏋' => 'HP', - '㏌' => 'in', - '㏍' => 'KK', - '㏎' => 'KM', - '㏏' => 'kt', - '㏐' => 'lm', - '㏑' => 'ln', - '㏒' => 'log', - '㏓' => 'lx', - '㏔' => 'mb', - '㏕' => 'mil', - '㏖' => 'mol', - '㏗' => 'PH', - '㏘' => 'p.m.', - '㏙' => 'PPM', - '㏚' => 'PR', - '㏛' => 'sr', - '㏜' => 'Sv', - '㏝' => 'Wb', - '㏞' => 'V∕m', - '㏟' => 'A∕m', - '㏠' => '1日', - '㏡' => '2日', - '㏢' => '3日', - '㏣' => '4日', - '㏤' => '5日', - '㏥' => '6日', - '㏦' => '7日', - '㏧' => '8日', - '㏨' => '9日', - '㏩' => '10日', - '㏪' => '11日', - '㏫' => '12日', - '㏬' => '13日', - '㏭' => '14日', - '㏮' => '15日', - '㏯' => '16日', - '㏰' => '17日', - '㏱' => '18日', - '㏲' => '19日', - '㏳' => '20日', - '㏴' => '21日', - '㏵' => '22日', - '㏶' => '23日', - '㏷' => '24日', - '㏸' => '25日', - '㏹' => '26日', - '㏺' => '27日', - '㏻' => '28日', - '㏼' => '29日', - '㏽' => '30日', - '㏾' => '31日', - '㏿' => 'gal', - 'ꚜ' => 'ъ', - 'ꚝ' => 'ь', - 'ꝰ' => 'ꝯ', - 'ꟸ' => 'Ħ', - 'ꟹ' => 'œ', - 'ꭜ' => 'ꜧ', - 'ꭝ' => 'ꬷ', - 'ꭞ' => 'ɫ', - 'ꭟ' => 'ꭒ', - 'ꭩ' => 'ʍ', - 'ff' => 'ff', - 'fi' => 'fi', - 'fl' => 'fl', - 'ffi' => 'ffi', - 'ffl' => 'ffl', - 'ſt' => 'st', - 'st' => 'st', - 'ﬓ' => 'մն', - 'ﬔ' => 'մե', - 'ﬕ' => 'մի', - 'ﬖ' => 'վն', - 'ﬗ' => 'մխ', - 'ﬠ' => 'ע', - 'ﬡ' => 'א', - 'ﬢ' => 'ד', - 'ﬣ' => 'ה', - 'ﬤ' => 'כ', - 'ﬥ' => 'ל', - 'ﬦ' => 'ם', - 'ﬧ' => 'ר', - 'ﬨ' => 'ת', - '﬩' => '+', - 'ﭏ' => 'אל', - 'ﭐ' => 'ٱ', - 'ﭑ' => 'ٱ', - 'ﭒ' => 'ٻ', - 'ﭓ' => 'ٻ', - 'ﭔ' => 'ٻ', - 'ﭕ' => 'ٻ', - 'ﭖ' => 'پ', - 'ﭗ' => 'پ', - 'ﭘ' => 'پ', - 'ﭙ' => 'پ', - 'ﭚ' => 'ڀ', - 'ﭛ' => 'ڀ', - 'ﭜ' => 'ڀ', - 'ﭝ' => 'ڀ', - 'ﭞ' => 'ٺ', - 'ﭟ' => 'ٺ', - 'ﭠ' => 'ٺ', - 'ﭡ' => 'ٺ', - 'ﭢ' => 'ٿ', - 'ﭣ' => 'ٿ', - 'ﭤ' => 'ٿ', - 'ﭥ' => 'ٿ', - 'ﭦ' => 'ٹ', - 'ﭧ' => 'ٹ', - 'ﭨ' => 'ٹ', - 'ﭩ' => 'ٹ', - 'ﭪ' => 'ڤ', - 'ﭫ' => 'ڤ', - 'ﭬ' => 'ڤ', - 'ﭭ' => 'ڤ', - 'ﭮ' => 'ڦ', - 'ﭯ' => 'ڦ', - 'ﭰ' => 'ڦ', - 'ﭱ' => 'ڦ', - 'ﭲ' => 'ڄ', - 'ﭳ' => 'ڄ', - 'ﭴ' => 'ڄ', - 'ﭵ' => 'ڄ', - 'ﭶ' => 'ڃ', - 'ﭷ' => 'ڃ', - 'ﭸ' => 'ڃ', - 'ﭹ' => 'ڃ', - 'ﭺ' => 'چ', - 'ﭻ' => 'چ', - 'ﭼ' => 'چ', - 'ﭽ' => 'چ', - 'ﭾ' => 'ڇ', - 'ﭿ' => 'ڇ', - 'ﮀ' => 'ڇ', - 'ﮁ' => 'ڇ', - 'ﮂ' => 'ڍ', - 'ﮃ' => 'ڍ', - 'ﮄ' => 'ڌ', - 'ﮅ' => 'ڌ', - 'ﮆ' => 'ڎ', - 'ﮇ' => 'ڎ', - 'ﮈ' => 'ڈ', - 'ﮉ' => 'ڈ', - 'ﮊ' => 'ژ', - 'ﮋ' => 'ژ', - 'ﮌ' => 'ڑ', - 'ﮍ' => 'ڑ', - 'ﮎ' => 'ک', - 'ﮏ' => 'ک', - 'ﮐ' => 'ک', - 'ﮑ' => 'ک', - 'ﮒ' => 'گ', - 'ﮓ' => 'گ', - 'ﮔ' => 'گ', - 'ﮕ' => 'گ', - 'ﮖ' => 'ڳ', - 'ﮗ' => 'ڳ', - 'ﮘ' => 'ڳ', - 'ﮙ' => 'ڳ', - 'ﮚ' => 'ڱ', - 'ﮛ' => 'ڱ', - 'ﮜ' => 'ڱ', - 'ﮝ' => 'ڱ', - 'ﮞ' => 'ں', - 'ﮟ' => 'ں', - 'ﮠ' => 'ڻ', - 'ﮡ' => 'ڻ', - 'ﮢ' => 'ڻ', - 'ﮣ' => 'ڻ', - 'ﮤ' => 'ۀ', - 'ﮥ' => 'ۀ', - 'ﮦ' => 'ہ', - 'ﮧ' => 'ہ', - 'ﮨ' => 'ہ', - 'ﮩ' => 'ہ', - 'ﮪ' => 'ھ', - 'ﮫ' => 'ھ', - 'ﮬ' => 'ھ', - 'ﮭ' => 'ھ', - 'ﮮ' => 'ے', - 'ﮯ' => 'ے', - 'ﮰ' => 'ۓ', - 'ﮱ' => 'ۓ', - 'ﯓ' => 'ڭ', - 'ﯔ' => 'ڭ', - 'ﯕ' => 'ڭ', - 'ﯖ' => 'ڭ', - 'ﯗ' => 'ۇ', - 'ﯘ' => 'ۇ', - 'ﯙ' => 'ۆ', - 'ﯚ' => 'ۆ', - 'ﯛ' => 'ۈ', - 'ﯜ' => 'ۈ', - 'ﯝ' => 'ۇٴ', - 'ﯞ' => 'ۋ', - 'ﯟ' => 'ۋ', - 'ﯠ' => 'ۅ', - 'ﯡ' => 'ۅ', - 'ﯢ' => 'ۉ', - 'ﯣ' => 'ۉ', - 'ﯤ' => 'ې', - 'ﯥ' => 'ې', - 'ﯦ' => 'ې', - 'ﯧ' => 'ې', - 'ﯨ' => 'ى', - 'ﯩ' => 'ى', - 'ﯪ' => 'ئا', - 'ﯫ' => 'ئا', - 'ﯬ' => 'ئە', - 'ﯭ' => 'ئە', - 'ﯮ' => 'ئو', - 'ﯯ' => 'ئو', - 'ﯰ' => 'ئۇ', - 'ﯱ' => 'ئۇ', - 'ﯲ' => 'ئۆ', - 'ﯳ' => 'ئۆ', - 'ﯴ' => 'ئۈ', - 'ﯵ' => 'ئۈ', - 'ﯶ' => 'ئې', - 'ﯷ' => 'ئې', - 'ﯸ' => 'ئې', - 'ﯹ' => 'ئى', - 'ﯺ' => 'ئى', - 'ﯻ' => 'ئى', - 'ﯼ' => 'ی', - 'ﯽ' => 'ی', - 'ﯾ' => 'ی', - 'ﯿ' => 'ی', - 'ﰀ' => 'ئج', - 'ﰁ' => 'ئح', - 'ﰂ' => 'ئم', - 'ﰃ' => 'ئى', - 'ﰄ' => 'ئي', - 'ﰅ' => 'بج', - 'ﰆ' => 'بح', - 'ﰇ' => 'بخ', - 'ﰈ' => 'بم', - 'ﰉ' => 'بى', - 'ﰊ' => 'بي', - 'ﰋ' => 'تج', - 'ﰌ' => 'تح', - 'ﰍ' => 'تخ', - 'ﰎ' => 'تم', - 'ﰏ' => 'تى', - 'ﰐ' => 'تي', - 'ﰑ' => 'ثج', - 'ﰒ' => 'ثم', - 'ﰓ' => 'ثى', - 'ﰔ' => 'ثي', - 'ﰕ' => 'جح', - 'ﰖ' => 'جم', - 'ﰗ' => 'حج', - 'ﰘ' => 'حم', - 'ﰙ' => 'خج', - 'ﰚ' => 'خح', - 'ﰛ' => 'خم', - 'ﰜ' => 'سج', - 'ﰝ' => 'سح', - 'ﰞ' => 'سخ', - 'ﰟ' => 'سم', - 'ﰠ' => 'صح', - 'ﰡ' => 'صم', - 'ﰢ' => 'ضج', - 'ﰣ' => 'ضح', - 'ﰤ' => 'ضخ', - 'ﰥ' => 'ضم', - 'ﰦ' => 'طح', - 'ﰧ' => 'طم', - 'ﰨ' => 'ظم', - 'ﰩ' => 'عج', - 'ﰪ' => 'عم', - 'ﰫ' => 'غج', - 'ﰬ' => 'غم', - 'ﰭ' => 'فج', - 'ﰮ' => 'فح', - 'ﰯ' => 'فخ', - 'ﰰ' => 'فم', - 'ﰱ' => 'فى', - 'ﰲ' => 'في', - 'ﰳ' => 'قح', - 'ﰴ' => 'قم', - 'ﰵ' => 'قى', - 'ﰶ' => 'قي', - 'ﰷ' => 'كا', - 'ﰸ' => 'كج', - 'ﰹ' => 'كح', - 'ﰺ' => 'كخ', - 'ﰻ' => 'كل', - 'ﰼ' => 'كم', - 'ﰽ' => 'كى', - 'ﰾ' => 'كي', - 'ﰿ' => 'لج', - 'ﱀ' => 'لح', - 'ﱁ' => 'لخ', - 'ﱂ' => 'لم', - 'ﱃ' => 'لى', - 'ﱄ' => 'لي', - 'ﱅ' => 'مج', - 'ﱆ' => 'مح', - 'ﱇ' => 'مخ', - 'ﱈ' => 'مم', - 'ﱉ' => 'مى', - 'ﱊ' => 'مي', - 'ﱋ' => 'نج', - 'ﱌ' => 'نح', - 'ﱍ' => 'نخ', - 'ﱎ' => 'نم', - 'ﱏ' => 'نى', - 'ﱐ' => 'ني', - 'ﱑ' => 'هج', - 'ﱒ' => 'هم', - 'ﱓ' => 'هى', - 'ﱔ' => 'هي', - 'ﱕ' => 'يج', - 'ﱖ' => 'يح', - 'ﱗ' => 'يخ', - 'ﱘ' => 'يم', - 'ﱙ' => 'يى', - 'ﱚ' => 'يي', - 'ﱛ' => 'ذٰ', - 'ﱜ' => 'رٰ', - 'ﱝ' => 'ىٰ', - 'ﱞ' => ' ٌّ', - 'ﱟ' => ' ٍّ', - 'ﱠ' => ' َّ', - 'ﱡ' => ' ُّ', - 'ﱢ' => ' ِّ', - 'ﱣ' => ' ّٰ', - 'ﱤ' => 'ئر', - 'ﱥ' => 'ئز', - 'ﱦ' => 'ئم', - 'ﱧ' => 'ئن', - 'ﱨ' => 'ئى', - 'ﱩ' => 'ئي', - 'ﱪ' => 'بر', - 'ﱫ' => 'بز', - 'ﱬ' => 'بم', - 'ﱭ' => 'بن', - 'ﱮ' => 'بى', - 'ﱯ' => 'بي', - 'ﱰ' => 'تر', - 'ﱱ' => 'تز', - 'ﱲ' => 'تم', - 'ﱳ' => 'تن', - 'ﱴ' => 'تى', - 'ﱵ' => 'تي', - 'ﱶ' => 'ثر', - 'ﱷ' => 'ثز', - 'ﱸ' => 'ثم', - 'ﱹ' => 'ثن', - 'ﱺ' => 'ثى', - 'ﱻ' => 'ثي', - 'ﱼ' => 'فى', - 'ﱽ' => 'في', - 'ﱾ' => 'قى', - 'ﱿ' => 'قي', - 'ﲀ' => 'كا', - 'ﲁ' => 'كل', - 'ﲂ' => 'كم', - 'ﲃ' => 'كى', - 'ﲄ' => 'كي', - 'ﲅ' => 'لم', - 'ﲆ' => 'لى', - 'ﲇ' => 'لي', - 'ﲈ' => 'ما', - 'ﲉ' => 'مم', - 'ﲊ' => 'نر', - 'ﲋ' => 'نز', - 'ﲌ' => 'نم', - 'ﲍ' => 'نن', - 'ﲎ' => 'نى', - 'ﲏ' => 'ني', - 'ﲐ' => 'ىٰ', - 'ﲑ' => 'ير', - 'ﲒ' => 'يز', - 'ﲓ' => 'يم', - 'ﲔ' => 'ين', - 'ﲕ' => 'يى', - 'ﲖ' => 'يي', - 'ﲗ' => 'ئج', - 'ﲘ' => 'ئح', - 'ﲙ' => 'ئخ', - 'ﲚ' => 'ئم', - 'ﲛ' => 'ئه', - 'ﲜ' => 'بج', - 'ﲝ' => 'بح', - 'ﲞ' => 'بخ', - 'ﲟ' => 'بم', - 'ﲠ' => 'به', - 'ﲡ' => 'تج', - 'ﲢ' => 'تح', - 'ﲣ' => 'تخ', - 'ﲤ' => 'تم', - 'ﲥ' => 'ته', - 'ﲦ' => 'ثم', - 'ﲧ' => 'جح', - 'ﲨ' => 'جم', - 'ﲩ' => 'حج', - 'ﲪ' => 'حم', - 'ﲫ' => 'خج', - 'ﲬ' => 'خم', - 'ﲭ' => 'سج', - 'ﲮ' => 'سح', - 'ﲯ' => 'سخ', - 'ﲰ' => 'سم', - 'ﲱ' => 'صح', - 'ﲲ' => 'صخ', - 'ﲳ' => 'صم', - 'ﲴ' => 'ضج', - 'ﲵ' => 'ضح', - 'ﲶ' => 'ضخ', - 'ﲷ' => 'ضم', - 'ﲸ' => 'طح', - 'ﲹ' => 'ظم', - 'ﲺ' => 'عج', - 'ﲻ' => 'عم', - 'ﲼ' => 'غج', - 'ﲽ' => 'غم', - 'ﲾ' => 'فج', - 'ﲿ' => 'فح', - 'ﳀ' => 'فخ', - 'ﳁ' => 'فم', - 'ﳂ' => 'قح', - 'ﳃ' => 'قم', - 'ﳄ' => 'كج', - 'ﳅ' => 'كح', - 'ﳆ' => 'كخ', - 'ﳇ' => 'كل', - 'ﳈ' => 'كم', - 'ﳉ' => 'لج', - 'ﳊ' => 'لح', - 'ﳋ' => 'لخ', - 'ﳌ' => 'لم', - 'ﳍ' => 'له', - 'ﳎ' => 'مج', - 'ﳏ' => 'مح', - 'ﳐ' => 'مخ', - 'ﳑ' => 'مم', - 'ﳒ' => 'نج', - 'ﳓ' => 'نح', - 'ﳔ' => 'نخ', - 'ﳕ' => 'نم', - 'ﳖ' => 'نه', - 'ﳗ' => 'هج', - 'ﳘ' => 'هم', - 'ﳙ' => 'هٰ', - 'ﳚ' => 'يج', - 'ﳛ' => 'يح', - 'ﳜ' => 'يخ', - 'ﳝ' => 'يم', - 'ﳞ' => 'يه', - 'ﳟ' => 'ئم', - 'ﳠ' => 'ئه', - 'ﳡ' => 'بم', - 'ﳢ' => 'به', - 'ﳣ' => 'تم', - 'ﳤ' => 'ته', - 'ﳥ' => 'ثم', - 'ﳦ' => 'ثه', - 'ﳧ' => 'سم', - 'ﳨ' => 'سه', - 'ﳩ' => 'شم', - 'ﳪ' => 'شه', - 'ﳫ' => 'كل', - 'ﳬ' => 'كم', - 'ﳭ' => 'لم', - 'ﳮ' => 'نم', - 'ﳯ' => 'نه', - 'ﳰ' => 'يم', - 'ﳱ' => 'يه', - 'ﳲ' => 'ـَّ', - 'ﳳ' => 'ـُّ', - 'ﳴ' => 'ـِّ', - 'ﳵ' => 'طى', - 'ﳶ' => 'طي', - 'ﳷ' => 'عى', - 'ﳸ' => 'عي', - 'ﳹ' => 'غى', - 'ﳺ' => 'غي', - 'ﳻ' => 'سى', - 'ﳼ' => 'سي', - 'ﳽ' => 'شى', - 'ﳾ' => 'شي', - 'ﳿ' => 'حى', - 'ﴀ' => 'حي', - 'ﴁ' => 'جى', - 'ﴂ' => 'جي', - 'ﴃ' => 'خى', - 'ﴄ' => 'خي', - 'ﴅ' => 'صى', - 'ﴆ' => 'صي', - 'ﴇ' => 'ضى', - 'ﴈ' => 'ضي', - 'ﴉ' => 'شج', - 'ﴊ' => 'شح', - 'ﴋ' => 'شخ', - 'ﴌ' => 'شم', - 'ﴍ' => 'شر', - 'ﴎ' => 'سر', - 'ﴏ' => 'صر', - 'ﴐ' => 'ضر', - 'ﴑ' => 'طى', - 'ﴒ' => 'طي', - 'ﴓ' => 'عى', - 'ﴔ' => 'عي', - 'ﴕ' => 'غى', - 'ﴖ' => 'غي', - 'ﴗ' => 'سى', - 'ﴘ' => 'سي', - 'ﴙ' => 'شى', - 'ﴚ' => 'شي', - 'ﴛ' => 'حى', - 'ﴜ' => 'حي', - 'ﴝ' => 'جى', - 'ﴞ' => 'جي', - 'ﴟ' => 'خى', - 'ﴠ' => 'خي', - 'ﴡ' => 'صى', - 'ﴢ' => 'صي', - 'ﴣ' => 'ضى', - 'ﴤ' => 'ضي', - 'ﴥ' => 'شج', - 'ﴦ' => 'شح', - 'ﴧ' => 'شخ', - 'ﴨ' => 'شم', - 'ﴩ' => 'شر', - 'ﴪ' => 'سر', - 'ﴫ' => 'صر', - 'ﴬ' => 'ضر', - 'ﴭ' => 'شج', - 'ﴮ' => 'شح', - 'ﴯ' => 'شخ', - 'ﴰ' => 'شم', - 'ﴱ' => 'سه', - 'ﴲ' => 'شه', - 'ﴳ' => 'طم', - 'ﴴ' => 'سج', - 'ﴵ' => 'سح', - 'ﴶ' => 'سخ', - 'ﴷ' => 'شج', - 'ﴸ' => 'شح', - 'ﴹ' => 'شخ', - 'ﴺ' => 'طم', - 'ﴻ' => 'ظم', - 'ﴼ' => 'اً', - 'ﴽ' => 'اً', - 'ﵐ' => 'تجم', - 'ﵑ' => 'تحج', - 'ﵒ' => 'تحج', - 'ﵓ' => 'تحم', - 'ﵔ' => 'تخم', - 'ﵕ' => 'تمج', - 'ﵖ' => 'تمح', - 'ﵗ' => 'تمخ', - 'ﵘ' => 'جمح', - 'ﵙ' => 'جمح', - 'ﵚ' => 'حمي', - 'ﵛ' => 'حمى', - 'ﵜ' => 'سحج', - 'ﵝ' => 'سجح', - 'ﵞ' => 'سجى', - 'ﵟ' => 'سمح', - 'ﵠ' => 'سمح', - 'ﵡ' => 'سمج', - 'ﵢ' => 'سمم', - 'ﵣ' => 'سمم', - 'ﵤ' => 'صحح', - 'ﵥ' => 'صحح', - 'ﵦ' => 'صمم', - 'ﵧ' => 'شحم', - 'ﵨ' => 'شحم', - 'ﵩ' => 'شجي', - 'ﵪ' => 'شمخ', - 'ﵫ' => 'شمخ', - 'ﵬ' => 'شمم', - 'ﵭ' => 'شمم', - 'ﵮ' => 'ضحى', - 'ﵯ' => 'ضخم', - 'ﵰ' => 'ضخم', - 'ﵱ' => 'طمح', - 'ﵲ' => 'طمح', - 'ﵳ' => 'طمم', - 'ﵴ' => 'طمي', - 'ﵵ' => 'عجم', - 'ﵶ' => 'عمم', - 'ﵷ' => 'عمم', - 'ﵸ' => 'عمى', - 'ﵹ' => 'غمم', - 'ﵺ' => 'غمي', - 'ﵻ' => 'غمى', - 'ﵼ' => 'فخم', - 'ﵽ' => 'فخم', - 'ﵾ' => 'قمح', - 'ﵿ' => 'قمم', - 'ﶀ' => 'لحم', - 'ﶁ' => 'لحي', - 'ﶂ' => 'لحى', - 'ﶃ' => 'لجج', - 'ﶄ' => 'لجج', - 'ﶅ' => 'لخم', - 'ﶆ' => 'لخم', - 'ﶇ' => 'لمح', - 'ﶈ' => 'لمح', - 'ﶉ' => 'محج', - 'ﶊ' => 'محم', - 'ﶋ' => 'محي', - 'ﶌ' => 'مجح', - 'ﶍ' => 'مجم', - 'ﶎ' => 'مخج', - 'ﶏ' => 'مخم', - 'ﶒ' => 'مجخ', - 'ﶓ' => 'همج', - 'ﶔ' => 'همم', - 'ﶕ' => 'نحم', - 'ﶖ' => 'نحى', - 'ﶗ' => 'نجم', - 'ﶘ' => 'نجم', - 'ﶙ' => 'نجى', - 'ﶚ' => 'نمي', - 'ﶛ' => 'نمى', - 'ﶜ' => 'يمم', - 'ﶝ' => 'يمم', - 'ﶞ' => 'بخي', - 'ﶟ' => 'تجي', - 'ﶠ' => 'تجى', - 'ﶡ' => 'تخي', - 'ﶢ' => 'تخى', - 'ﶣ' => 'تمي', - 'ﶤ' => 'تمى', - 'ﶥ' => 'جمي', - 'ﶦ' => 'جحى', - 'ﶧ' => 'جمى', - 'ﶨ' => 'سخى', - 'ﶩ' => 'صحي', - 'ﶪ' => 'شحي', - 'ﶫ' => 'ضحي', - 'ﶬ' => 'لجي', - 'ﶭ' => 'لمي', - 'ﶮ' => 'يحي', - 'ﶯ' => 'يجي', - 'ﶰ' => 'يمي', - 'ﶱ' => 'ممي', - 'ﶲ' => 'قمي', - 'ﶳ' => 'نحي', - 'ﶴ' => 'قمح', - 'ﶵ' => 'لحم', - 'ﶶ' => 'عمي', - 'ﶷ' => 'كمي', - 'ﶸ' => 'نجح', - 'ﶹ' => 'مخي', - 'ﶺ' => 'لجم', - 'ﶻ' => 'كمم', - 'ﶼ' => 'لجم', - 'ﶽ' => 'نجح', - 'ﶾ' => 'جحي', - 'ﶿ' => 'حجي', - 'ﷀ' => 'مجي', - 'ﷁ' => 'فمي', - 'ﷂ' => 'بحي', - 'ﷃ' => 'كمم', - 'ﷄ' => 'عجم', - 'ﷅ' => 'صمم', - 'ﷆ' => 'سخي', - 'ﷇ' => 'نجي', - 'ﷰ' => 'صلے', - 'ﷱ' => 'قلے', - 'ﷲ' => 'الله', - 'ﷳ' => 'اكبر', - 'ﷴ' => 'محمد', - 'ﷵ' => 'صلعم', - 'ﷶ' => 'رسول', - 'ﷷ' => 'عليه', - 'ﷸ' => 'وسلم', - 'ﷹ' => 'صلى', - 'ﷺ' => 'صلى الله عليه وسلم', - 'ﷻ' => 'جل جلاله', - '﷼' => 'ریال', - '︐' => ',', - '︑' => '、', - '︒' => '。', - '︓' => ':', - '︔' => ';', - '︕' => '!', - '︖' => '?', - '︗' => '〖', - '︘' => '〗', - '︙' => '...', - '︰' => '..', - '︱' => '—', - '︲' => '–', - '︳' => '_', - '︴' => '_', - '︵' => '(', - '︶' => ')', - '︷' => '{', - '︸' => '}', - '︹' => '〔', - '︺' => '〕', - '︻' => '【', - '︼' => '】', - '︽' => '《', - '︾' => '》', - '︿' => '〈', - '﹀' => '〉', - '﹁' => '「', - '﹂' => '」', - '﹃' => '『', - '﹄' => '』', - '﹇' => '[', - '﹈' => ']', - '﹉' => ' ̅', - '﹊' => ' ̅', - '﹋' => ' ̅', - '﹌' => ' ̅', - '﹍' => '_', - '﹎' => '_', - '﹏' => '_', - '﹐' => ',', - '﹑' => '、', - '﹒' => '.', - '﹔' => ';', - '﹕' => ':', - '﹖' => '?', - '﹗' => '!', - '﹘' => '—', - '﹙' => '(', - '﹚' => ')', - '﹛' => '{', - '﹜' => '}', - '﹝' => '〔', - '﹞' => '〕', - '﹟' => '#', - '﹠' => '&', - '﹡' => '*', - '﹢' => '+', - '﹣' => '-', - '﹤' => '<', - '﹥' => '>', - '﹦' => '=', - '﹨' => '\\', - '﹩' => '$', - '﹪' => '%', - '﹫' => '@', - 'ﹰ' => ' ً', - 'ﹱ' => 'ـً', - 'ﹲ' => ' ٌ', - 'ﹴ' => ' ٍ', - 'ﹶ' => ' َ', - 'ﹷ' => 'ـَ', - 'ﹸ' => ' ُ', - 'ﹹ' => 'ـُ', - 'ﹺ' => ' ِ', - 'ﹻ' => 'ـِ', - 'ﹼ' => ' ّ', - 'ﹽ' => 'ـّ', - 'ﹾ' => ' ْ', - 'ﹿ' => 'ـْ', - 'ﺀ' => 'ء', - 'ﺁ' => 'آ', - 'ﺂ' => 'آ', - 'ﺃ' => 'أ', - 'ﺄ' => 'أ', - 'ﺅ' => 'ؤ', - 'ﺆ' => 'ؤ', - 'ﺇ' => 'إ', - 'ﺈ' => 'إ', - 'ﺉ' => 'ئ', - 'ﺊ' => 'ئ', - 'ﺋ' => 'ئ', - 'ﺌ' => 'ئ', - 'ﺍ' => 'ا', - 'ﺎ' => 'ا', - 'ﺏ' => 'ب', - 'ﺐ' => 'ب', - 'ﺑ' => 'ب', - 'ﺒ' => 'ب', - 'ﺓ' => 'ة', - 'ﺔ' => 'ة', - 'ﺕ' => 'ت', - 'ﺖ' => 'ت', - 'ﺗ' => 'ت', - 'ﺘ' => 'ت', - 'ﺙ' => 'ث', - 'ﺚ' => 'ث', - 'ﺛ' => 'ث', - 'ﺜ' => 'ث', - 'ﺝ' => 'ج', - 'ﺞ' => 'ج', - 'ﺟ' => 'ج', - 'ﺠ' => 'ج', - 'ﺡ' => 'ح', - 'ﺢ' => 'ح', - 'ﺣ' => 'ح', - 'ﺤ' => 'ح', - 'ﺥ' => 'خ', - 'ﺦ' => 'خ', - 'ﺧ' => 'خ', - 'ﺨ' => 'خ', - 'ﺩ' => 'د', - 'ﺪ' => 'د', - 'ﺫ' => 'ذ', - 'ﺬ' => 'ذ', - 'ﺭ' => 'ر', - 'ﺮ' => 'ر', - 'ﺯ' => 'ز', - 'ﺰ' => 'ز', - 'ﺱ' => 'س', - 'ﺲ' => 'س', - 'ﺳ' => 'س', - 'ﺴ' => 'س', - 'ﺵ' => 'ش', - 'ﺶ' => 'ش', - 'ﺷ' => 'ش', - 'ﺸ' => 'ش', - 'ﺹ' => 'ص', - 'ﺺ' => 'ص', - 'ﺻ' => 'ص', - 'ﺼ' => 'ص', - 'ﺽ' => 'ض', - 'ﺾ' => 'ض', - 'ﺿ' => 'ض', - 'ﻀ' => 'ض', - 'ﻁ' => 'ط', - 'ﻂ' => 'ط', - 'ﻃ' => 'ط', - 'ﻄ' => 'ط', - 'ﻅ' => 'ظ', - 'ﻆ' => 'ظ', - 'ﻇ' => 'ظ', - 'ﻈ' => 'ظ', - 'ﻉ' => 'ع', - 'ﻊ' => 'ع', - 'ﻋ' => 'ع', - 'ﻌ' => 'ع', - 'ﻍ' => 'غ', - 'ﻎ' => 'غ', - 'ﻏ' => 'غ', - 'ﻐ' => 'غ', - 'ﻑ' => 'ف', - 'ﻒ' => 'ف', - 'ﻓ' => 'ف', - 'ﻔ' => 'ف', - 'ﻕ' => 'ق', - 'ﻖ' => 'ق', - 'ﻗ' => 'ق', - 'ﻘ' => 'ق', - 'ﻙ' => 'ك', - 'ﻚ' => 'ك', - 'ﻛ' => 'ك', - 'ﻜ' => 'ك', - 'ﻝ' => 'ل', - 'ﻞ' => 'ل', - 'ﻟ' => 'ل', - 'ﻠ' => 'ل', - 'ﻡ' => 'م', - 'ﻢ' => 'م', - 'ﻣ' => 'م', - 'ﻤ' => 'م', - 'ﻥ' => 'ن', - 'ﻦ' => 'ن', - 'ﻧ' => 'ن', - 'ﻨ' => 'ن', - 'ﻩ' => 'ه', - 'ﻪ' => 'ه', - 'ﻫ' => 'ه', - 'ﻬ' => 'ه', - 'ﻭ' => 'و', - 'ﻮ' => 'و', - 'ﻯ' => 'ى', - 'ﻰ' => 'ى', - 'ﻱ' => 'ي', - 'ﻲ' => 'ي', - 'ﻳ' => 'ي', - 'ﻴ' => 'ي', - 'ﻵ' => 'لآ', - 'ﻶ' => 'لآ', - 'ﻷ' => 'لأ', - 'ﻸ' => 'لأ', - 'ﻹ' => 'لإ', - 'ﻺ' => 'لإ', - 'ﻻ' => 'لا', - 'ﻼ' => 'لا', - '!' => '!', - '"' => '"', - '#' => '#', - '$' => '$', - '%' => '%', - '&' => '&', - ''' => '\'', - '(' => '(', - ')' => ')', - '*' => '*', - '+' => '+', - ',' => ',', - '-' => '-', - '.' => '.', - '/' => '/', - '0' => '0', - '1' => '1', - '2' => '2', - '3' => '3', - '4' => '4', - '5' => '5', - '6' => '6', - '7' => '7', - '8' => '8', - '9' => '9', - ':' => ':', - ';' => ';', - '<' => '<', - '=' => '=', - '>' => '>', - '?' => '?', - '@' => '@', - 'A' => 'A', - 'B' => 'B', - 'C' => 'C', - 'D' => 'D', - 'E' => 'E', - 'F' => 'F', - 'G' => 'G', - 'H' => 'H', - 'I' => 'I', - 'J' => 'J', - 'K' => 'K', - 'L' => 'L', - 'M' => 'M', - 'N' => 'N', - 'O' => 'O', - 'P' => 'P', - 'Q' => 'Q', - 'R' => 'R', - 'S' => 'S', - 'T' => 'T', - 'U' => 'U', - 'V' => 'V', - 'W' => 'W', - 'X' => 'X', - 'Y' => 'Y', - 'Z' => 'Z', - '[' => '[', - '\' => '\\', - ']' => ']', - '^' => '^', - '_' => '_', - '`' => '`', - 'a' => 'a', - 'b' => 'b', - 'c' => 'c', - 'd' => 'd', - 'e' => 'e', - 'f' => 'f', - 'g' => 'g', - 'h' => 'h', - 'i' => 'i', - 'j' => 'j', - 'k' => 'k', - 'l' => 'l', - 'm' => 'm', - 'n' => 'n', - 'o' => 'o', - 'p' => 'p', - 'q' => 'q', - 'r' => 'r', - 's' => 's', - 't' => 't', - 'u' => 'u', - 'v' => 'v', - 'w' => 'w', - 'x' => 'x', - 'y' => 'y', - 'z' => 'z', - '{' => '{', - '|' => '|', - '}' => '}', - '~' => '~', - '⦅' => '⦅', - '⦆' => '⦆', - '。' => '。', - '「' => '「', - '」' => '」', - '、' => '、', - '・' => '・', - 'ヲ' => 'ヲ', - 'ァ' => 'ァ', - 'ィ' => 'ィ', - 'ゥ' => 'ゥ', - 'ェ' => 'ェ', - 'ォ' => 'ォ', - 'ャ' => 'ャ', - 'ュ' => 'ュ', - 'ョ' => 'ョ', - 'ッ' => 'ッ', - 'ー' => 'ー', - 'ア' => 'ア', - 'イ' => 'イ', - 'ウ' => 'ウ', - 'エ' => 'エ', - 'オ' => 'オ', - 'カ' => 'カ', - 'キ' => 'キ', - 'ク' => 'ク', - 'ケ' => 'ケ', - 'コ' => 'コ', - 'サ' => 'サ', - 'シ' => 'シ', - 'ス' => 'ス', - 'セ' => 'セ', - 'ソ' => 'ソ', - 'タ' => 'タ', - 'チ' => 'チ', - 'ツ' => 'ツ', - 'テ' => 'テ', - 'ト' => 'ト', - 'ナ' => 'ナ', - 'ニ' => 'ニ', - 'ヌ' => 'ヌ', - 'ネ' => 'ネ', - 'ノ' => 'ノ', - 'ハ' => 'ハ', - 'ヒ' => 'ヒ', - 'フ' => 'フ', - 'ヘ' => 'ヘ', - 'ホ' => 'ホ', - 'マ' => 'マ', - 'ミ' => 'ミ', - 'ム' => 'ム', - 'メ' => 'メ', - 'モ' => 'モ', - 'ヤ' => 'ヤ', - 'ユ' => 'ユ', - 'ヨ' => 'ヨ', - 'ラ' => 'ラ', - 'リ' => 'リ', - 'ル' => 'ル', - 'レ' => 'レ', - 'ロ' => 'ロ', - 'ワ' => 'ワ', - 'ン' => 'ン', - '゙' => '゙', - '゚' => '゚', - 'ᅠ' => 'ᅠ', - 'ᄀ' => 'ᄀ', - 'ᄁ' => 'ᄁ', - 'ᆪ' => 'ᆪ', - 'ᄂ' => 'ᄂ', - 'ᆬ' => 'ᆬ', - 'ᆭ' => 'ᆭ', - 'ᄃ' => 'ᄃ', - 'ᄄ' => 'ᄄ', - 'ᄅ' => 'ᄅ', - 'ᆰ' => 'ᆰ', - 'ᆱ' => 'ᆱ', - 'ᆲ' => 'ᆲ', - 'ᆳ' => 'ᆳ', - 'ᆴ' => 'ᆴ', - 'ᆵ' => 'ᆵ', - 'ᄚ' => 'ᄚ', - 'ᄆ' => 'ᄆ', - 'ᄇ' => 'ᄇ', - 'ᄈ' => 'ᄈ', - 'ᄡ' => 'ᄡ', - 'ᄉ' => 'ᄉ', - 'ᄊ' => 'ᄊ', - 'ᄋ' => 'ᄋ', - 'ᄌ' => 'ᄌ', - 'ᄍ' => 'ᄍ', - 'ᄎ' => 'ᄎ', - 'ᄏ' => 'ᄏ', - 'ᄐ' => 'ᄐ', - 'ᄑ' => 'ᄑ', - 'ᄒ' => 'ᄒ', - 'ᅡ' => 'ᅡ', - 'ᅢ' => 'ᅢ', - 'ᅣ' => 'ᅣ', - 'ᅤ' => 'ᅤ', - 'ᅥ' => 'ᅥ', - 'ᅦ' => 'ᅦ', - 'ᅧ' => 'ᅧ', - 'ᅨ' => 'ᅨ', - 'ᅩ' => 'ᅩ', - 'ᅪ' => 'ᅪ', - 'ᅫ' => 'ᅫ', - 'ᅬ' => 'ᅬ', - 'ᅭ' => 'ᅭ', - 'ᅮ' => 'ᅮ', - 'ᅯ' => 'ᅯ', - 'ᅰ' => 'ᅰ', - 'ᅱ' => 'ᅱ', - 'ᅲ' => 'ᅲ', - 'ᅳ' => 'ᅳ', - 'ᅴ' => 'ᅴ', - 'ᅵ' => 'ᅵ', - '¢' => '¢', - '£' => '£', - '¬' => '¬', - ' ̄' => ' ̄', - '¦' => '¦', - '¥' => '¥', - '₩' => '₩', - '│' => '│', - '←' => '←', - '↑' => '↑', - '→' => '→', - '↓' => '↓', - '■' => '■', - '○' => '○', - '𝐀' => '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', - '𝐚' => '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', - '𝐴' => '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', - '𝑎' => 'a', - '𝑏' => 'b', - '𝑐' => 'c', - '𝑑' => 'd', - '𝑒' => 'e', - '𝑓' => 'f', - '𝑔' => 'g', - '𝑖' => 'i', - '𝑗' => 'j', - '𝑘' => 'k', - '𝑙' => 'l', - '𝑚' => 'm', - '𝑛' => 'n', - '𝑜' => 'o', - '𝑝' => 'p', - '𝑞' => 'q', - '𝑟' => 'r', - '𝑠' => 's', - '𝑡' => 't', - '𝑢' => 'u', - '𝑣' => 'v', - '𝑤' => 'w', - '𝑥' => 'x', - '𝑦' => 'y', - '𝑧' => 'z', - '𝑨' => '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', - '𝒂' => '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', - '𝒜' => 'A', - '𝒞' => 'C', - '𝒟' => 'D', - '𝒢' => 'G', - '𝒥' => 'J', - '𝒦' => 'K', - '𝒩' => 'N', - '𝒪' => 'O', - '𝒫' => 'P', - '𝒬' => 'Q', - '𝒮' => 'S', - '𝒯' => 'T', - '𝒰' => 'U', - '𝒱' => 'V', - '𝒲' => 'W', - '𝒳' => 'X', - '𝒴' => 'Y', - '𝒵' => 'Z', - '𝒶' => 'a', - '𝒷' => 'b', - '𝒸' => 'c', - '𝒹' => 'd', - '𝒻' => 'f', - '𝒽' => 'h', - '𝒾' => 'i', - '𝒿' => 'j', - '𝓀' => 'k', - '𝓁' => 'l', - '𝓂' => 'm', - '𝓃' => 'n', - '𝓅' => 'p', - '𝓆' => 'q', - '𝓇' => 'r', - '𝓈' => 's', - '𝓉' => 't', - '𝓊' => 'u', - '𝓋' => 'v', - '𝓌' => 'w', - '𝓍' => 'x', - '𝓎' => 'y', - '𝓏' => 'z', - '𝓐' => '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', - '𝓪' => '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', - '𝔄' => 'A', - '𝔅' => 'B', - '𝔇' => 'D', - '𝔈' => 'E', - '𝔉' => 'F', - '𝔊' => 'G', - '𝔍' => 'J', - '𝔎' => 'K', - '𝔏' => 'L', - '𝔐' => 'M', - '𝔑' => 'N', - '𝔒' => 'O', - '𝔓' => 'P', - '𝔔' => 'Q', - '𝔖' => 'S', - '𝔗' => 'T', - '𝔘' => 'U', - '𝔙' => 'V', - '𝔚' => 'W', - '𝔛' => 'X', - '𝔜' => 'Y', - '𝔞' => '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', - '𝔸' => 'A', - '𝔹' => 'B', - '𝔻' => 'D', - '𝔼' => 'E', - '𝔽' => 'F', - '𝔾' => 'G', - '𝕀' => 'I', - '𝕁' => 'J', - '𝕂' => 'K', - '𝕃' => 'L', - '𝕄' => 'M', - '𝕆' => 'O', - '𝕊' => 'S', - '𝕋' => 'T', - '𝕌' => 'U', - '𝕍' => 'V', - '𝕎' => 'W', - '𝕏' => 'X', - '𝕐' => 'Y', - '𝕒' => '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', - '𝕬' => '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', - '𝖆' => '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', - '𝖠' => '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', - '𝖺' => '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', - '𝗔' => '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', - '𝗮' => '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', - '𝘈' => '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', - '𝘢' => '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', - '𝘼' => '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', - '𝙖' => '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', - '𝙰' => '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', - '𝚊' => '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', - '𝚤' => 'ı', - '𝚥' => 'ȷ', - '𝚨' => 'Α', - '𝚩' => 'Β', - '𝚪' => 'Γ', - '𝚫' => 'Δ', - '𝚬' => 'Ε', - '𝚭' => 'Ζ', - '𝚮' => 'Η', - '𝚯' => 'Θ', - '𝚰' => 'Ι', - '𝚱' => 'Κ', - '𝚲' => 'Λ', - '𝚳' => 'Μ', - '𝚴' => 'Ν', - '𝚵' => 'Ξ', - '𝚶' => 'Ο', - '𝚷' => 'Π', - '𝚸' => 'Ρ', - '𝚹' => 'Θ', - '𝚺' => 'Σ', - '𝚻' => 'Τ', - '𝚼' => 'Υ', - '𝚽' => 'Φ', - '𝚾' => 'Χ', - '𝚿' => 'Ψ', - '𝛀' => 'Ω', - '𝛁' => '∇', - '𝛂' => 'α', - '𝛃' => 'β', - '𝛄' => 'γ', - '𝛅' => 'δ', - '𝛆' => 'ε', - '𝛇' => 'ζ', - '𝛈' => 'η', - '𝛉' => 'θ', - '𝛊' => 'ι', - '𝛋' => 'κ', - '𝛌' => 'λ', - '𝛍' => 'μ', - '𝛎' => 'ν', - '𝛏' => 'ξ', - '𝛐' => 'ο', - '𝛑' => 'π', - '𝛒' => 'ρ', - '𝛓' => 'ς', - '𝛔' => 'σ', - '𝛕' => 'τ', - '𝛖' => 'υ', - '𝛗' => 'φ', - '𝛘' => 'χ', - '𝛙' => 'ψ', - '𝛚' => 'ω', - '𝛛' => '∂', - '𝛜' => 'ε', - '𝛝' => 'θ', - '𝛞' => 'κ', - '𝛟' => 'φ', - '𝛠' => 'ρ', - '𝛡' => 'π', - '𝛢' => 'Α', - '𝛣' => 'Β', - '𝛤' => 'Γ', - '𝛥' => 'Δ', - '𝛦' => 'Ε', - '𝛧' => 'Ζ', - '𝛨' => 'Η', - '𝛩' => 'Θ', - '𝛪' => 'Ι', - '𝛫' => 'Κ', - '𝛬' => 'Λ', - '𝛭' => 'Μ', - '𝛮' => 'Ν', - '𝛯' => 'Ξ', - '𝛰' => 'Ο', - '𝛱' => 'Π', - '𝛲' => 'Ρ', - '𝛳' => 'Θ', - '𝛴' => 'Σ', - '𝛵' => 'Τ', - '𝛶' => 'Υ', - '𝛷' => 'Φ', - '𝛸' => 'Χ', - '𝛹' => 'Ψ', - '𝛺' => 'Ω', - '𝛻' => '∇', - '𝛼' => 'α', - '𝛽' => 'β', - '𝛾' => 'γ', - '𝛿' => 'δ', - '𝜀' => 'ε', - '𝜁' => 'ζ', - '𝜂' => 'η', - '𝜃' => 'θ', - '𝜄' => 'ι', - '𝜅' => 'κ', - '𝜆' => 'λ', - '𝜇' => 'μ', - '𝜈' => 'ν', - '𝜉' => 'ξ', - '𝜊' => 'ο', - '𝜋' => 'π', - '𝜌' => 'ρ', - '𝜍' => 'ς', - '𝜎' => 'σ', - '𝜏' => 'τ', - '𝜐' => 'υ', - '𝜑' => 'φ', - '𝜒' => 'χ', - '𝜓' => 'ψ', - '𝜔' => 'ω', - '𝜕' => '∂', - '𝜖' => 'ε', - '𝜗' => 'θ', - '𝜘' => 'κ', - '𝜙' => 'φ', - '𝜚' => 'ρ', - '𝜛' => 'π', - '𝜜' => 'Α', - '𝜝' => 'Β', - '𝜞' => 'Γ', - '𝜟' => 'Δ', - '𝜠' => 'Ε', - '𝜡' => 'Ζ', - '𝜢' => 'Η', - '𝜣' => 'Θ', - '𝜤' => 'Ι', - '𝜥' => 'Κ', - '𝜦' => 'Λ', - '𝜧' => 'Μ', - '𝜨' => 'Ν', - '𝜩' => 'Ξ', - '𝜪' => 'Ο', - '𝜫' => 'Π', - '𝜬' => 'Ρ', - '𝜭' => 'Θ', - '𝜮' => 'Σ', - '𝜯' => 'Τ', - '𝜰' => 'Υ', - '𝜱' => 'Φ', - '𝜲' => 'Χ', - '𝜳' => 'Ψ', - '𝜴' => 'Ω', - '𝜵' => '∇', - '𝜶' => 'α', - '𝜷' => 'β', - '𝜸' => 'γ', - '𝜹' => 'δ', - '𝜺' => 'ε', - '𝜻' => 'ζ', - '𝜼' => 'η', - '𝜽' => 'θ', - '𝜾' => 'ι', - '𝜿' => 'κ', - '𝝀' => 'λ', - '𝝁' => 'μ', - '𝝂' => 'ν', - '𝝃' => 'ξ', - '𝝄' => 'ο', - '𝝅' => 'π', - '𝝆' => 'ρ', - '𝝇' => 'ς', - '𝝈' => 'σ', - '𝝉' => 'τ', - '𝝊' => 'υ', - '𝝋' => 'φ', - '𝝌' => 'χ', - '𝝍' => 'ψ', - '𝝎' => 'ω', - '𝝏' => '∂', - '𝝐' => 'ε', - '𝝑' => 'θ', - '𝝒' => 'κ', - '𝝓' => 'φ', - '𝝔' => 'ρ', - '𝝕' => 'π', - '𝝖' => 'Α', - '𝝗' => 'Β', - '𝝘' => 'Γ', - '𝝙' => 'Δ', - '𝝚' => 'Ε', - '𝝛' => 'Ζ', - '𝝜' => 'Η', - '𝝝' => 'Θ', - '𝝞' => 'Ι', - '𝝟' => 'Κ', - '𝝠' => 'Λ', - '𝝡' => 'Μ', - '𝝢' => 'Ν', - '𝝣' => 'Ξ', - '𝝤' => 'Ο', - '𝝥' => 'Π', - '𝝦' => 'Ρ', - '𝝧' => 'Θ', - '𝝨' => 'Σ', - '𝝩' => 'Τ', - '𝝪' => 'Υ', - '𝝫' => 'Φ', - '𝝬' => 'Χ', - '𝝭' => 'Ψ', - '𝝮' => 'Ω', - '𝝯' => '∇', - '𝝰' => 'α', - '𝝱' => 'β', - '𝝲' => 'γ', - '𝝳' => 'δ', - '𝝴' => 'ε', - '𝝵' => 'ζ', - '𝝶' => 'η', - '𝝷' => 'θ', - '𝝸' => 'ι', - '𝝹' => 'κ', - '𝝺' => 'λ', - '𝝻' => 'μ', - '𝝼' => 'ν', - '𝝽' => 'ξ', - '𝝾' => 'ο', - '𝝿' => 'π', - '𝞀' => 'ρ', - '𝞁' => 'ς', - '𝞂' => 'σ', - '𝞃' => 'τ', - '𝞄' => 'υ', - '𝞅' => 'φ', - '𝞆' => 'χ', - '𝞇' => 'ψ', - '𝞈' => 'ω', - '𝞉' => '∂', - '𝞊' => 'ε', - '𝞋' => 'θ', - '𝞌' => 'κ', - '𝞍' => 'φ', - '𝞎' => 'ρ', - '𝞏' => 'π', - '𝞐' => 'Α', - '𝞑' => 'Β', - '𝞒' => 'Γ', - '𝞓' => 'Δ', - '𝞔' => 'Ε', - '𝞕' => 'Ζ', - '𝞖' => 'Η', - '𝞗' => 'Θ', - '𝞘' => 'Ι', - '𝞙' => 'Κ', - '𝞚' => 'Λ', - '𝞛' => 'Μ', - '𝞜' => 'Ν', - '𝞝' => 'Ξ', - '𝞞' => 'Ο', - '𝞟' => 'Π', - '𝞠' => 'Ρ', - '𝞡' => 'Θ', - '𝞢' => 'Σ', - '𝞣' => 'Τ', - '𝞤' => 'Υ', - '𝞥' => 'Φ', - '𝞦' => 'Χ', - '𝞧' => 'Ψ', - '𝞨' => 'Ω', - '𝞩' => '∇', - '𝞪' => 'α', - '𝞫' => 'β', - '𝞬' => 'γ', - '𝞭' => 'δ', - '𝞮' => 'ε', - '𝞯' => 'ζ', - '𝞰' => 'η', - '𝞱' => 'θ', - '𝞲' => 'ι', - '𝞳' => 'κ', - '𝞴' => 'λ', - '𝞵' => 'μ', - '𝞶' => 'ν', - '𝞷' => 'ξ', - '𝞸' => 'ο', - '𝞹' => 'π', - '𝞺' => 'ρ', - '𝞻' => 'ς', - '𝞼' => 'σ', - '𝞽' => 'τ', - '𝞾' => 'υ', - '𝞿' => 'φ', - '𝟀' => 'χ', - '𝟁' => 'ψ', - '𝟂' => 'ω', - '𝟃' => '∂', - '𝟄' => 'ε', - '𝟅' => 'θ', - '𝟆' => 'κ', - '𝟇' => 'φ', - '𝟈' => 'ρ', - '𝟉' => 'π', - '𝟊' => 'Ϝ', - '𝟋' => 'ϝ', - '𝟎' => '0', - '𝟏' => '1', - '𝟐' => '2', - '𝟑' => '3', - '𝟒' => '4', - '𝟓' => '5', - '𝟔' => '6', - '𝟕' => '7', - '𝟖' => '8', - '𝟗' => '9', - '𝟘' => '0', - '𝟙' => '1', - '𝟚' => '2', - '𝟛' => '3', - '𝟜' => '4', - '𝟝' => '5', - '𝟞' => '6', - '𝟟' => '7', - '𝟠' => '8', - '𝟡' => '9', - '𝟢' => '0', - '𝟣' => '1', - '𝟤' => '2', - '𝟥' => '3', - '𝟦' => '4', - '𝟧' => '5', - '𝟨' => '6', - '𝟩' => '7', - '𝟪' => '8', - '𝟫' => '9', - '𝟬' => '0', - '𝟭' => '1', - '𝟮' => '2', - '𝟯' => '3', - '𝟰' => '4', - '𝟱' => '5', - '𝟲' => '6', - '𝟳' => '7', - '𝟴' => '8', - '𝟵' => '9', - '𝟶' => '0', - '𝟷' => '1', - '𝟸' => '2', - '𝟹' => '3', - '𝟺' => '4', - '𝟻' => '5', - '𝟼' => '6', - '𝟽' => '7', - '𝟾' => '8', - '𝟿' => '9', - '𞸀' => 'ا', - '𞸁' => 'ب', - '𞸂' => 'ج', - '𞸃' => 'د', - '𞸅' => 'و', - '𞸆' => 'ز', - '𞸇' => 'ح', - '𞸈' => 'ط', - '𞸉' => 'ي', - '𞸊' => 'ك', - '𞸋' => 'ل', - '𞸌' => 'م', - '𞸍' => 'ن', - '𞸎' => 'س', - '𞸏' => 'ع', - '𞸐' => 'ف', - '𞸑' => 'ص', - '𞸒' => 'ق', - '𞸓' => 'ر', - '𞸔' => 'ش', - '𞸕' => 'ت', - '𞸖' => 'ث', - '𞸗' => 'خ', - '𞸘' => 'ذ', - '𞸙' => 'ض', - '𞸚' => 'ظ', - '𞸛' => 'غ', - '𞸜' => 'ٮ', - '𞸝' => 'ں', - '𞸞' => 'ڡ', - '𞸟' => 'ٯ', - '𞸡' => 'ب', - '𞸢' => 'ج', - '𞸤' => 'ه', - '𞸧' => 'ح', - '𞸩' => 'ي', - '𞸪' => 'ك', - '𞸫' => 'ل', - '𞸬' => 'م', - '𞸭' => 'ن', - '𞸮' => 'س', - '𞸯' => 'ع', - '𞸰' => 'ف', - '𞸱' => 'ص', - '𞸲' => 'ق', - '𞸴' => 'ش', - '𞸵' => 'ت', - '𞸶' => 'ث', - '𞸷' => 'خ', - '𞸹' => 'ض', - '𞸻' => 'غ', - '𞹂' => 'ج', - '𞹇' => 'ح', - '𞹉' => 'ي', - '𞹋' => 'ل', - '𞹍' => 'ن', - '𞹎' => 'س', - '𞹏' => 'ع', - '𞹑' => 'ص', - '𞹒' => 'ق', - '𞹔' => 'ش', - '𞹗' => 'خ', - '𞹙' => 'ض', - '𞹛' => 'غ', - '𞹝' => 'ں', - '𞹟' => 'ٯ', - '𞹡' => 'ب', - '𞹢' => 'ج', - '𞹤' => 'ه', - '𞹧' => 'ح', - '𞹨' => 'ط', - '𞹩' => 'ي', - '𞹪' => 'ك', - '𞹬' => 'م', - '𞹭' => 'ن', - '𞹮' => 'س', - '𞹯' => 'ع', - '𞹰' => 'ف', - '𞹱' => 'ص', - '𞹲' => 'ق', - '𞹴' => 'ش', - '𞹵' => 'ت', - '𞹶' => 'ث', - '𞹷' => 'خ', - '𞹹' => 'ض', - '𞹺' => 'ظ', - '𞹻' => 'غ', - '𞹼' => 'ٮ', - '𞹾' => 'ڡ', - '𞺀' => 'ا', - '𞺁' => 'ب', - '𞺂' => 'ج', - '𞺃' => 'د', - '𞺄' => 'ه', - '𞺅' => 'و', - '𞺆' => 'ز', - '𞺇' => 'ح', - '𞺈' => 'ط', - '𞺉' => 'ي', - '𞺋' => 'ل', - '𞺌' => 'م', - '𞺍' => 'ن', - '𞺎' => 'س', - '𞺏' => 'ع', - '𞺐' => 'ف', - '𞺑' => 'ص', - '𞺒' => 'ق', - '𞺓' => 'ر', - '𞺔' => 'ش', - '𞺕' => 'ت', - '𞺖' => 'ث', - '𞺗' => 'خ', - '𞺘' => 'ذ', - '𞺙' => 'ض', - '𞺚' => 'ظ', - '𞺛' => 'غ', - '𞺡' => 'ب', - '𞺢' => 'ج', - '𞺣' => 'د', - '𞺥' => 'و', - '𞺦' => 'ز', - '𞺧' => 'ح', - '𞺨' => 'ط', - '𞺩' => 'ي', - '𞺫' => 'ل', - '𞺬' => 'م', - '𞺭' => 'ن', - '𞺮' => 'س', - '𞺯' => 'ع', - '𞺰' => 'ف', - '𞺱' => 'ص', - '𞺲' => 'ق', - '𞺳' => 'ر', - '𞺴' => 'ش', - '𞺵' => 'ت', - '𞺶' => 'ث', - '𞺷' => 'خ', - '𞺸' => 'ذ', - '𞺹' => 'ض', - '𞺺' => 'ظ', - '𞺻' => 'غ', - '🄀' => '0.', - '🄁' => '0,', - '🄂' => '1,', - '🄃' => '2,', - '🄄' => '3,', - '🄅' => '4,', - '🄆' => '5,', - '🄇' => '6,', - '🄈' => '7,', - '🄉' => '8,', - '🄊' => '9,', - '🄐' => '(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)', - '🄪' => '〔S〕', - '🄫' => 'C', - '🄬' => 'R', - '🄭' => 'CD', - '🄮' => 'WZ', - '🄰' => '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', - '🅊' => 'HV', - '🅋' => 'MV', - '🅌' => 'SD', - '🅍' => 'SS', - '🅎' => 'PPV', - '🅏' => 'WC', - '🅪' => 'MC', - '🅫' => 'MD', - '🅬' => 'MR', - '🆐' => 'DJ', - '🈀' => 'ほか', - '🈁' => 'ココ', - '🈂' => 'サ', - '🈐' => '手', - '🈑' => '字', - '🈒' => '双', - '🈓' => 'デ', - '🈔' => '二', - '🈕' => '多', - '🈖' => '解', - '🈗' => '天', - '🈘' => '交', - '🈙' => '映', - '🈚' => '無', - '🈛' => '料', - '🈜' => '前', - '🈝' => '後', - '🈞' => '再', - '🈟' => '新', - '🈠' => '初', - '🈡' => '終', - '🈢' => '生', - '🈣' => '販', - '🈤' => '声', - '🈥' => '吹', - '🈦' => '演', - '🈧' => '投', - '🈨' => '捕', - '🈩' => '一', - '🈪' => '三', - '🈫' => '遊', - '🈬' => '左', - '🈭' => '中', - '🈮' => '右', - '🈯' => '指', - '🈰' => '走', - '🈱' => '打', - '🈲' => '禁', - '🈳' => '空', - '🈴' => '合', - '🈵' => '満', - '🈶' => '有', - '🈷' => '月', - '🈸' => '申', - '🈹' => '割', - '🈺' => '営', - '🈻' => '配', - '🉀' => '〔本〕', - '🉁' => '〔三〕', - '🉂' => '〔二〕', - '🉃' => '〔安〕', - '🉄' => '〔点〕', - '🉅' => '〔打〕', - '🉆' => '〔盗〕', - '🉇' => '〔勝〕', - '🉈' => '〔敗〕', - '🉐' => '得', - '🉑' => '可', - '🯰' => '0', - '🯱' => '1', - '🯲' => '2', - '🯳' => '3', - '🯴' => '4', - '🯵' => '5', - '🯶' => '6', - '🯷' => '7', - '🯸' => '8', - '🯹' => '9', -); diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap.php deleted file mode 100644 index 3608e5c05..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Normalizer as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } -} -if (!function_exists('normalizer_normalize')) { - function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap80.php b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap80.php deleted file mode 100644 index e36d1a947..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/bootstrap80.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Normalizer as p; - -if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } -} -if (!function_exists('normalizer_normalize')) { - function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/composer.json b/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/composer.json deleted file mode 100644 index 2c4de2c83..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-intl-normalizer/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "symfony/polyfill-intl-normalizer", - "type": "library", - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"], - "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\\Intl\\Normalizer\\": "" }, - "files": [ "bootstrap.php" ], - "classmap": [ "Resources/stubs" ] - }, - "suggest": { - "ext-intl": "For best performance" - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/lam/lib/3rdParty/composer/symfony/polyfill-php72/LICENSE b/lam/lib/3rdParty/composer/symfony/polyfill-php72/LICENSE deleted file mode 100644 index 6e3afce69..000000000 --- a/lam/lib/3rdParty/composer/symfony/polyfill-php72/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-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/lam/lib/3rdParty/composer/symfony/polyfill-php72/Php72.php b/lam/lib/3rdParty/composer/symfony/polyfill-php72/Php72.php deleted file mode 100644 index 7bf96c996..000000000 --- a/lam/lib/3rdParty/composer/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/lam/lib/3rdParty/composer/symfony/polyfill-php72/README.md b/lam/lib/3rdParty/composer/symfony/polyfill-php72/README.md deleted file mode 100644 index ed1905055..000000000 --- a/lam/lib/3rdParty/composer/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/lam/lib/3rdParty/composer/symfony/polyfill-php72/bootstrap.php b/lam/lib/3rdParty/composer/symfony/polyfill-php72/bootstrap.php deleted file mode 100644 index b5c92d4c7..000000000 --- a/lam/lib/3rdParty/composer/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/lam/lib/3rdParty/composer/symfony/polyfill-php72/composer.json b/lam/lib/3rdParty/composer/symfony/polyfill-php72/composer.json deleted file mode 100644 index b61b4c8a2..000000000 --- a/lam/lib/3rdParty/composer/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/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.gitignore b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.gitignore deleted file mode 100644 index 082fd221e..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -vendor/ -composer.lock -phpunit.xml -.php_cs.cache -.phpunit.result.cache diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php_cs.dist b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php-cs-fixer.dist.php similarity index 91% rename from lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php_cs.dist rename to lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php-cs-fixer.dist.php index d741d39f5..e9b256a14 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php_cs.dist +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.php-cs-fixer.dist.php @@ -1,6 +1,6 @@ setRules([ '@Symfony' => true, '@Symfony:risky' => true, @@ -17,8 +17,9 @@ ]) ->setRiskyAllowed(true) ->setFinder( - PhpCsFixer\Finder::create() + (new PhpCsFixer\Finder()) ->in(__DIR__) + ->exclude('vendor') ->name('*.php') ) ; diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.travis.yml b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.travis.yml deleted file mode 100644 index d171c0035..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/.travis.yml +++ /dev/null @@ -1,48 +0,0 @@ -language: php -sudo: false -cache: - directories: - - $HOME/.composer/cache/files - - $HOME/symfony-bridge/.phpunit - -env: - global: - - PHPUNIT_FLAGS="-v" - - SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit" - -matrix: - fast_finish: true - include: - # Minimum supported dependencies with the latest and oldest PHP version - - php: 7.3 - env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" SYMFONY_DEPRECATIONS_HELPER="weak_vendors" - - - php: 7.1 - - php: 7.2 - - php: 7.3 - env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text" - - # Latest commit to master - - php: 7.3 - env: STABILITY="dev" - - allow_failures: - # Dev-master is allowed to fail. - - env: STABILITY="dev" - -before_install: - - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi - - if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi; - - if ! [ -v "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi; - -install: - # To be removed when this issue will be resolved: https://github.com/composer/composer/issues/5355 - - if [[ "$COMPOSER_FLAGS" == *"--prefer-lowest"* ]]; then composer update --prefer-dist --no-interaction --prefer-stable --quiet; fi - - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction - - ./vendor/bin/simple-phpunit install - -script: - - composer validate --strict --no-check-lock - # simple-phpunit is the PHPUnit wrapper provided by the PHPUnit Bridge component and - # it helps with testing legacy code and deprecations (composer require symfony/phpunit-bridge) - - ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/PsrServerRequestResolver.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/PsrServerRequestResolver.php new file mode 100644 index 000000000..61cd8c5c5 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/PsrServerRequestResolver.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver; + +use Psr\Http\Message\MessageInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; +use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; +use Symfony\Component\HttpKernel\Controller\ValueResolverInterface as BaseValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Injects the RequestInterface, MessageInterface or ServerRequestInterface when requested. + * + * @author Iltar van der Berg + * @author Alexander M. Turek + */ +final class PsrServerRequestResolver implements ArgumentValueResolverInterface, ValueResolverInterface +{ + private const SUPPORTED_TYPES = [ + ServerRequestInterface::class => true, + RequestInterface::class => true, + MessageInterface::class => true, + ]; + + private $httpMessageFactory; + + public function __construct(HttpMessageFactoryInterface $httpMessageFactory) + { + $this->httpMessageFactory = $httpMessageFactory; + } + + /** + * {@inheritdoc} + */ + public function supports(Request $request, ArgumentMetadata $argument): bool + { + if ($this instanceof BaseValueResolverInterface) { + trigger_deprecation('symfony/psr-http-message-bridge', '2.3', 'Method "%s" is deprecated, call "resolve()" without calling "supports()" first.', __METHOD__); + } + + return self::SUPPORTED_TYPES[$argument->getType()] ?? false; + } + + /** + * {@inheritdoc} + */ + public function resolve(Request $request, ArgumentMetadata $argument): \Traversable + { + if (!isset(self::SUPPORTED_TYPES[$argument->getType()])) { + return; + } + + yield $this->httpMessageFactory->createRequest($request); + } +} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/ValueResolverInterface.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/ValueResolverInterface.php new file mode 100644 index 000000000..83a321ab7 --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/ArgumentValueResolver/ValueResolverInterface.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\Bridge\PsrHttpMessage\ArgumentValueResolver; + +use Symfony\Component\HttpKernel\Controller\ValueResolverInterface as BaseValueResolverInterface; + +if (interface_exists(BaseValueResolverInterface::class)) { + /** @internal */ + interface ValueResolverInterface extends BaseValueResolverInterface + { + } +} else { + /** @internal */ + interface ValueResolverInterface + { + } +} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/CHANGELOG.md b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/CHANGELOG.md index 1559be284..f32c06f2e 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/CHANGELOG.md @@ -1,40 +1,85 @@ CHANGELOG ========= -* 1.3.0 (2019-11-25) +# 2.3.1 (2023-07-26) + +* Don't rely on `Request::getPayload()` to populate the parsed body + +# 2.3.0 (2023-07-25) + +* Leverage `Request::getPayload()` to populate the parsed body of PSR-7 requests +* Implement `ValueResolverInterface` introduced with Symfony 6.2 + +# 2.2.0 (2023-04-21) + +* Drop support for Symfony 4 +* Bump minimum version of PHP to 7.2 +* Support version 2 of the psr/http-message contracts + +# 2.1.3 (2022-09-05) + +* Ignore invalid HTTP headers when creating PSR7 objects +* Fix for wrong type passed to `moveTo()` + +# 2.1.2 (2021-11-05) + +* Allow Symfony 6 + +# 2.1.0 (2021-02-17) + + * Added a `PsrResponseListener` to automatically convert PSR-7 responses returned by controllers + * Added a `PsrServerRequestResolver` that allows injecting PSR-7 request objects into controllers + +# 2.0.2 (2020-09-29) + + * Fix populating server params from URI in HttpFoundationFactory + * Create cookies as raw in HttpFoundationFactory + * Fix BinaryFileResponse with Content-Range PsrHttpFactory + +# 2.0.1 (2020-06-25) + + * Don't normalize query string in PsrHttpFactory + * Fix conversion for HTTPS requests + * Fix populating default port and headers in HttpFoundationFactory + +# 2.0.0 (2020-01-02) + + * Remove DiactorosFactory + +# 1.3.0 (2019-11-25) * Added support for streamed requests * Added support for Symfony 5.0+ * Fixed bridging UploadedFile objects * Bumped minimum version of Symfony to 4.4 -* 1.2.0 (2019-03-11) +# 1.2.0 (2019-03-11) * Added new documentation links * Bumped minimum version of PHP to 7.1 * Added support for streamed responses -* 1.1.2 (2019-04-03) +# 1.1.2 (2019-04-03) * Fixed createResponse -* 1.1.1 (2019-03-11) +# 1.1.1 (2019-03-11) * Deprecated DiactorosFactory, use PsrHttpFactory instead * Removed triggering of deprecation -* 1.1.0 (2018-08-30) +# 1.1.0 (2018-08-30) * Added support for creating PSR-7 messages using PSR-17 factories -* 1.0.2 (2017-12-19) +# 1.0.2 (2017-12-19) * Fixed request target in PSR7 Request (mtibben) -* 1.0.1 (2017-12-04) +# 1.0.1 (2017-12-04) * Added support for Symfony 4 (dunglas) -* 1.0.0 (2016-09-14) +# 1.0.0 (2016-09-14) * Initial release diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/EventListener/PsrResponseListener.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/EventListener/PsrResponseListener.php new file mode 100644 index 000000000..ee0e0476a --- /dev/null +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/EventListener/PsrResponseListener.php @@ -0,0 +1,50 @@ + + * @author Alexander M. Turek + */ +final class PsrResponseListener implements EventSubscriberInterface +{ + private $httpFoundationFactory; + + public function __construct(HttpFoundationFactoryInterface $httpFoundationFactory = null) + { + $this->httpFoundationFactory = $httpFoundationFactory ?? new HttpFoundationFactory(); + } + + /** + * Do the conversion if applicable and update the response of the event. + */ + public function onKernelView(ViewEvent $event): void + { + $controllerResult = $event->getControllerResult(); + + if (!$controllerResult instanceof ResponseInterface) { + return; + } + + $event->setResponse($this->httpFoundationFactory->createResponse($controllerResult)); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array + { + return [ + KernelEvents::VIEW => 'onKernelView', + ]; + } +} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php deleted file mode 100644 index cc87dd82d..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php +++ /dev/null @@ -1,171 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Factory; - -@trigger_error(sprintf('The "%s" class is deprecated since symfony/psr-http-message-bridge 1.2, use PsrHttpFactory instead.', DiactorosFactory::class), E_USER_DEPRECATED); - -use Psr\Http\Message\UploadedFileInterface; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\StreamedResponse; -use Zend\Diactoros\Response as DiactorosResponse; -use Zend\Diactoros\ServerRequest; -use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; -use Zend\Diactoros\Stream as DiactorosStream; -use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; - -/** - * Builds Psr\HttpMessage instances using the Zend Diactoros implementation. - * - * @author Kévin Dunglas - * - * @deprecated since symfony/psr-http-message-bridge 1.2, use PsrHttpFactory instead - */ -class DiactorosFactory implements HttpMessageFactoryInterface -{ - public function __construct() - { - if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { - throw new \RuntimeException('Zend Diactoros must be installed to use the DiactorosFactory.'); - } - } - - /** - * {@inheritdoc} - */ - public function createRequest(Request $symfonyRequest) - { - $server = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeServer') - ? DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all()) - : \Zend\Diactoros\normalizeServer($symfonyRequest->server->all()); - $headers = $symfonyRequest->headers->all(); - - $body = new DiactorosStream($symfonyRequest->getContent(true)); - - $files = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeFiles') - ? DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all())) - : \Zend\Diactoros\normalizeUploadedFiles($this->getFiles($symfonyRequest->files->all())); - - $request = new ServerRequest( - $server, - $files, - $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getRequestUri(), - $symfonyRequest->getMethod(), - $body, - $headers - ); - - $request = $request - ->withCookieParams($symfonyRequest->cookies->all()) - ->withQueryParams($symfonyRequest->query->all()) - ->withParsedBody($symfonyRequest->request->all()) - ->withRequestTarget($symfonyRequest->getRequestUri()) - ; - - foreach ($symfonyRequest->attributes->all() as $key => $value) { - $request = $request->withAttribute($key, $value); - } - - return $request; - } - - /** - * Converts Symfony uploaded files array to the PSR one. - * - * @return array - */ - private function getFiles(array $uploadedFiles) - { - $files = []; - - foreach ($uploadedFiles as $key => $value) { - if (null === $value) { - $files[$key] = new DiactorosUploadedFile(null, 0, UPLOAD_ERR_NO_FILE, null, null); - continue; - } - if ($value instanceof UploadedFile) { - $files[$key] = $this->createUploadedFile($value); - } else { - $files[$key] = $this->getFiles($value); - } - } - - return $files; - } - - /** - * Creates a PSR-7 UploadedFile instance from a Symfony one. - * - * @return UploadedFileInterface - */ - private function createUploadedFile(UploadedFile $symfonyUploadedFile) - { - return new DiactorosUploadedFile( - $symfonyUploadedFile->getRealPath(), - (int) $symfonyUploadedFile->getSize(), - $symfonyUploadedFile->getError(), - $symfonyUploadedFile->getClientOriginalName(), - $symfonyUploadedFile->getClientMimeType() - ); - } - - /** - * {@inheritdoc} - */ - public function createResponse(Response $symfonyResponse) - { - if ($symfonyResponse instanceof BinaryFileResponse) { - $stream = new DiactorosStream($symfonyResponse->getFile()->getPathname(), 'r'); - } else { - $stream = new DiactorosStream('php://temp', 'wb+'); - if ($symfonyResponse instanceof StreamedResponse) { - ob_start(function ($buffer) use ($stream) { - $stream->write($buffer); - - return ''; - }); - - $symfonyResponse->sendContent(); - ob_end_clean(); - } else { - $stream->write($symfonyResponse->getContent()); - } - } - - $headers = $symfonyResponse->headers->all(); - if (!isset($headers['Set-Cookie']) && !isset($headers['set-cookie'])) { - $cookies = $symfonyResponse->headers->getCookies(); - if (!empty($cookies)) { - $headers['Set-Cookie'] = []; - foreach ($cookies as $cookie) { - $headers['Set-Cookie'][] = $cookie->__toString(); - } - } - } - - $response = new DiactorosResponse( - $stream, - $symfonyResponse->getStatusCode(), - $headers - ); - - $protocolVersion = $symfonyResponse->getProtocolVersion(); - if ('1.1' !== $protocolVersion) { - $response = $response->withProtocolVersion($protocolVersion); - } - - return $response; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php index d9bbaf2dc..a69e8ffee 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php @@ -41,6 +41,8 @@ public function __construct(int $responseBufferMaxLength = 16372) /** * {@inheritdoc} + * + * @return Request */ public function createRequest(ServerRequestInterface $psrRequest, bool $streamed = false) { @@ -49,14 +51,22 @@ public function createRequest(ServerRequestInterface $psrRequest, bool $streamed if ($uri instanceof UriInterface) { $server['SERVER_NAME'] = $uri->getHost(); - $server['SERVER_PORT'] = $uri->getPort(); + $server['SERVER_PORT'] = $uri->getPort() ?: ('https' === $uri->getScheme() ? 443 : 80); $server['REQUEST_URI'] = $uri->getPath(); $server['QUERY_STRING'] = $uri->getQuery(); + + if ('' !== $server['QUERY_STRING']) { + $server['REQUEST_URI'] .= '?'.$server['QUERY_STRING']; + } + + if ('https' === $uri->getScheme()) { + $server['HTTPS'] = 'on'; + } } $server['REQUEST_METHOD'] = $psrRequest->getMethod(); - $server = array_replace($server, $psrRequest->getServerParams()); + $server = array_replace($psrRequest->getServerParams(), $server); $parsedBody = $psrRequest->getParsedBody(); $parsedBody = \is_array($parsedBody) ? $parsedBody : []; @@ -70,7 +80,7 @@ public function createRequest(ServerRequestInterface $psrRequest, bool $streamed $server, $streamed ? $psrRequest->getBody()->detach() : $psrRequest->getBody()->__toString() ); - $request->headers->replace($psrRequest->getHeaders()); + $request->headers->add($psrRequest->getHeaders()); return $request; } @@ -113,6 +123,8 @@ protected function getTemporaryPath() /** * {@inheritdoc} + * + * @return Response */ public function createResponse(ResponseInterface $psrResponse, bool $streamed = false) { @@ -209,13 +221,13 @@ private function createCookie(string $cookie): Cookie return new Cookie( $cookieName, $cookieValue, - isset($cookieExpire) ? $cookieExpire : 0, - isset($cookiePath) ? $cookiePath : '/', - isset($cookieDomain) ? $cookieDomain : null, + $cookieExpire ?? 0, + $cookiePath ?? '/', + $cookieDomain ?? null, isset($cookieSecure), isset($cookieHttpOnly), - false, - isset($samesite) ? $samesite : null + true, + $samesite ?? null ); } diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/PsrHttpFactory.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/PsrHttpFactory.php index dfcfe73b2..09c4360dd 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/PsrHttpFactory.php +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/PsrHttpFactory.php @@ -12,7 +12,9 @@ namespace Symfony\Bridge\PsrHttpMessage\Factory; use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestFactoryInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Http\Message\UploadedFileInterface; @@ -27,6 +29,7 @@ * Builds Psr\HttpMessage instances using a PSR-17 implementation. * * @author Antonio J. García Lagar + * @author Aurélien Pillevesse */ class PsrHttpFactory implements HttpMessageFactoryInterface { @@ -45,27 +48,52 @@ public function __construct(ServerRequestFactoryInterface $serverRequestFactory, /** * {@inheritdoc} + * + * @return ServerRequestInterface */ public function createRequest(Request $symfonyRequest) { + $uri = $symfonyRequest->server->get('QUERY_STRING', ''); + $uri = $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getBaseUrl().$symfonyRequest->getPathInfo().('' !== $uri ? '?'.$uri : ''); + $request = $this->serverRequestFactory->createServerRequest( $symfonyRequest->getMethod(), - $symfonyRequest->getUri(), + $uri, $symfonyRequest->server->all() ); foreach ($symfonyRequest->headers->all() as $name => $value) { - $request = $request->withHeader($name, $value); + try { + $request = $request->withHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } } $body = $this->streamFactory->createStreamFromResource($symfonyRequest->getContent(true)); + if (method_exists(Request::class, 'getContentTypeFormat')) { + $format = $symfonyRequest->getContentTypeFormat(); + } else { + $format = $symfonyRequest->getContentType(); + } + + if ('json' === $format) { + $parsedBody = json_decode($symfonyRequest->getContent(), true, 512, \JSON_BIGINT_AS_STRING); + + if (!\is_array($parsedBody)) { + $parsedBody = null; + } + } else { + $parsedBody = $symfonyRequest->request->all(); + } + $request = $request ->withBody($body) ->withUploadedFiles($this->getFiles($symfonyRequest->files->all())) ->withCookieParams($symfonyRequest->cookies->all()) ->withQueryParams($symfonyRequest->query->all()) - ->withParsedBody($symfonyRequest->request->all()) + ->withParsedBody($parsedBody) ; foreach ($symfonyRequest->attributes->all() as $key => $value) { @@ -77,16 +105,14 @@ public function createRequest(Request $symfonyRequest) /** * Converts Symfony uploaded files array to the PSR one. - * - * @return array */ - private function getFiles(array $uploadedFiles) + private function getFiles(array $uploadedFiles): array { $files = []; foreach ($uploadedFiles as $key => $value) { if (null === $value) { - $files[$key] = $this->uploadedFileFactory->createUploadedFile($this->streamFactory->createStream(), 0, UPLOAD_ERR_NO_FILE); + $files[$key] = $this->uploadedFileFactory->createUploadedFile($this->streamFactory->createStream(), 0, \UPLOAD_ERR_NO_FILE); continue; } if ($value instanceof UploadedFile) { @@ -101,10 +127,8 @@ private function getFiles(array $uploadedFiles) /** * Creates a PSR-7 UploadedFile instance from a Symfony one. - * - * @return UploadedFileInterface */ - private function createUploadedFile(UploadedFile $symfonyUploadedFile) + private function createUploadedFile(UploadedFile $symfonyUploadedFile): UploadedFileInterface { return $this->uploadedFileFactory->createUploadedFile( $this->streamFactory->createStreamFromFile( @@ -119,23 +143,25 @@ private function createUploadedFile(UploadedFile $symfonyUploadedFile) /** * {@inheritdoc} + * + * @return ResponseInterface */ public function createResponse(Response $symfonyResponse) { $response = $this->responseFactory->createResponse($symfonyResponse->getStatusCode(), Response::$statusTexts[$symfonyResponse->getStatusCode()] ?? ''); - if ($symfonyResponse instanceof BinaryFileResponse) { + if ($symfonyResponse instanceof BinaryFileResponse && !$symfonyResponse->headers->has('Content-Range')) { $stream = $this->streamFactory->createStreamFromFile( $symfonyResponse->getFile()->getPathname() ); } else { $stream = $this->streamFactory->createStreamFromFile('php://temp', 'wb+'); - if ($symfonyResponse instanceof StreamedResponse) { + if ($symfonyResponse instanceof StreamedResponse || $symfonyResponse instanceof BinaryFileResponse) { ob_start(function ($buffer) use ($stream) { $stream->write($buffer); return ''; - }); + }, 1); $symfonyResponse->sendContent(); ob_end_clean(); @@ -157,7 +183,11 @@ public function createResponse(Response $symfonyResponse) } foreach ($headers as $name => $value) { - $response = $response->withHeader($name, $value); + try { + $response = $response->withHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } } $protocolVersion = $symfonyResponse->getProtocolVersion(); diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/UploadedFile.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/UploadedFile.php index 804f7478e..4d38a1f7c 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/UploadedFile.php +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Factory/UploadedFile.php @@ -29,7 +29,7 @@ public function __construct(UploadedFileInterface $psrUploadedFile, callable $ge $error = $psrUploadedFile->getError(); $path = ''; - if (UPLOAD_ERR_NO_FILE !== $error) { + if (\UPLOAD_ERR_NO_FILE !== $error) { $path = $psrUploadedFile->getStream()->getMetadata('uri') ?? ''; if ($this->test = !\is_string($path) || !is_uploaded_file($path)) { @@ -52,7 +52,7 @@ public function __construct(UploadedFileInterface $psrUploadedFile, callable $ge /** * {@inheritdoc} */ - public function move($directory, $name = null): File + public function move(string $directory, string $name = null): File { if (!$this->isValid() || $this->test) { return parent::move($directory, $name); @@ -61,7 +61,7 @@ public function move($directory, $name = null): File $target = $this->getTargetFile($directory, $name); try { - $this->psrUploadedFile->moveTo($target); + $this->psrUploadedFile->moveTo((string) $target); } catch (\RuntimeException $e) { throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, $e->getMessage()), 0, $e); } diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/LICENSE b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/LICENSE index 12a74531e..9ff2d0d63 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/LICENSE +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2016 Fabien Potencier +Copyright (c) 2004-2021 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/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/README.md b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/README.md index 87fbd43aa..dcbc09a84 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/README.md +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/README.md @@ -7,7 +7,6 @@ Resources --------- * [Documentation](https://symfony.com/doc/current/components/psr7.html) - * [SensioFrameworkExtraBundle](https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html#psr-7-support) Running the tests ----------------- diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/AbstractHttpMessageFactoryTest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/AbstractHttpMessageFactoryTest.php deleted file mode 100644 index 998edcc2f..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/AbstractHttpMessageFactoryTest.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\Bridge\PsrHttpMessage\Tests\Factory; - -use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\StreamedResponse; - -/** - * @author Kévin Dunglas - * @author Antonio J. García Lagar - */ -abstract class AbstractHttpMessageFactoryTest extends TestCase -{ - private $factory; - private $tmpDir; - - abstract protected function buildHttpMessageFactory(): HttpMessageFactoryInterface; - - public function setUp(): void - { - $this->factory = $this->buildHttpMessageFactory(); - $this->tmpDir = sys_get_temp_dir(); - } - - public function testCreateRequest() - { - $stdClass = new \stdClass(); - $request = new Request( - [ - 'bar' => ['baz' => '42'], - 'foo' => '1', - ], - [ - 'twitter' => [ - '@dunglas' => 'Kévin Dunglas', - '@coopTilleuls' => 'Les-Tilleuls.coop', - ], - 'baz' => '2', - ], - [ - 'a1' => $stdClass, - 'a2' => ['foo' => 'bar'], - ], - [ - 'c1' => 'foo', - 'c2' => ['c3' => 'bar'], - ], - [ - 'f1' => $this->createUploadedFile('F1', 'f1.txt', 'text/plain', UPLOAD_ERR_OK), - 'foo' => ['f2' => $this->createUploadedFile('F2', 'f2.txt', 'text/plain', UPLOAD_ERR_OK)], - ], - [ - 'REQUEST_METHOD' => 'POST', - 'HTTP_HOST' => 'dunglas.fr', - 'HTTP_X_SYMFONY' => '2.8', - 'REQUEST_URI' => '/testCreateRequest?bar[baz]=42&foo=1', - 'QUERY_STRING' => 'bar[baz]=42&foo=1', - ], - 'Content' - ); - - $psrRequest = $this->factory->createRequest($request); - - $this->assertEquals('Content', $psrRequest->getBody()->__toString()); - - $queryParams = $psrRequest->getQueryParams(); - $this->assertEquals('1', $queryParams['foo']); - $this->assertEquals('42', $queryParams['bar']['baz']); - - $requestTarget = $psrRequest->getRequestTarget(); - $this->assertEquals('/testCreateRequest?bar[baz]=42&foo=1', urldecode($requestTarget)); - - $parsedBody = $psrRequest->getParsedBody(); - $this->assertEquals('Kévin Dunglas', $parsedBody['twitter']['@dunglas']); - $this->assertEquals('Les-Tilleuls.coop', $parsedBody['twitter']['@coopTilleuls']); - $this->assertEquals('2', $parsedBody['baz']); - - $attributes = $psrRequest->getAttributes(); - $this->assertEquals($stdClass, $attributes['a1']); - $this->assertEquals('bar', $attributes['a2']['foo']); - - $cookies = $psrRequest->getCookieParams(); - $this->assertEquals('foo', $cookies['c1']); - $this->assertEquals('bar', $cookies['c2']['c3']); - - $uploadedFiles = $psrRequest->getUploadedFiles(); - $this->assertEquals('F1', $uploadedFiles['f1']->getStream()->__toString()); - $this->assertEquals('f1.txt', $uploadedFiles['f1']->getClientFilename()); - $this->assertEquals('text/plain', $uploadedFiles['f1']->getClientMediaType()); - $this->assertEquals(UPLOAD_ERR_OK, $uploadedFiles['f1']->getError()); - - $this->assertEquals('F2', $uploadedFiles['foo']['f2']->getStream()->__toString()); - $this->assertEquals('f2.txt', $uploadedFiles['foo']['f2']->getClientFilename()); - $this->assertEquals('text/plain', $uploadedFiles['foo']['f2']->getClientMediaType()); - $this->assertEquals(UPLOAD_ERR_OK, $uploadedFiles['foo']['f2']->getError()); - - $serverParams = $psrRequest->getServerParams(); - $this->assertEquals('POST', $serverParams['REQUEST_METHOD']); - $this->assertEquals('2.8', $serverParams['HTTP_X_SYMFONY']); - $this->assertEquals('POST', $psrRequest->getMethod()); - $this->assertEquals(['2.8'], $psrRequest->getHeader('X-Symfony')); - } - - public function testGetContentCanBeCalledAfterRequestCreation() - { - $header = ['HTTP_HOST' => 'dunglas.fr']; - $request = new Request([], [], [], [], [], $header, 'Content'); - - $psrRequest = $this->factory->createRequest($request); - - $this->assertEquals('Content', $psrRequest->getBody()->__toString()); - $this->assertEquals('Content', $request->getContent()); - } - - private function createUploadedFile($content, $originalName, $mimeType, $error) - { - $path = tempnam($this->tmpDir, uniqid()); - file_put_contents($path, $content); - - return new UploadedFile($path, $originalName, $mimeType, $error, true); - } - - public function testCreateResponse() - { - $response = new Response( - 'Response content.', - 202, - ['X-Symfony' => ['3.4']] - ); - $response->headers->setCookie(new Cookie('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT'), '/', null, false, true, false, 'lax')); - - $psrResponse = $this->factory->createResponse($response); - $this->assertEquals('Response content.', $psrResponse->getBody()->__toString()); - $this->assertEquals(202, $psrResponse->getStatusCode()); - $this->assertEquals(['3.4'], $psrResponse->getHeader('X-Symfony')); - - $cookieHeader = $psrResponse->getHeader('Set-Cookie'); - $this->assertIsArray($cookieHeader); - $this->assertCount(1, $cookieHeader); - $this->assertRegExp('{city=Lille; expires=Wed, 13-Jan-2021 22:23:01 GMT;( max-age=\d+;)? path=/; httponly}i', $cookieHeader[0]); - } - - public function testCreateResponseFromStreamed() - { - $response = new StreamedResponse(function () { - echo "Line 1\n"; - flush(); - - echo "Line 2\n"; - flush(); - }); - - $psrResponse = $this->factory->createResponse($response); - - $this->assertEquals("Line 1\nLine 2\n", $psrResponse->getBody()->__toString()); - } - - public function testCreateResponseFromBinaryFile() - { - $path = tempnam($this->tmpDir, uniqid()); - file_put_contents($path, 'Binary'); - - $response = new BinaryFileResponse($path); - - $psrResponse = $this->factory->createResponse($response); - - $this->assertEquals('Binary', $psrResponse->getBody()->__toString()); - } - - public function testUploadErrNoFile() - { - $file = new UploadedFile('', '', null, UPLOAD_ERR_NO_FILE, true); - - $this->assertEquals(0, $file->getSize()); - $this->assertEquals(UPLOAD_ERR_NO_FILE, $file->getError()); - $this->assertFalse($file->getSize(), 'SplFile::getSize() returns false on error'); - - $request = new Request( - [], - [], - [], - [], - [ - 'f1' => $file, - 'f2' => ['name' => null, 'type' => null, 'tmp_name' => null, 'error' => UPLOAD_ERR_NO_FILE, 'size' => 0], - ], - [ - 'REQUEST_METHOD' => 'POST', - 'HTTP_HOST' => 'dunglas.fr', - 'HTTP_X_SYMFONY' => '2.8', - ], - 'Content' - ); - - $psrRequest = $this->factory->createRequest($request); - - $uploadedFiles = $psrRequest->getUploadedFiles(); - - $this->assertEquals(UPLOAD_ERR_NO_FILE, $uploadedFiles['f1']->getError()); - $this->assertEquals(UPLOAD_ERR_NO_FILE, $uploadedFiles['f2']->getError()); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/DiactorosFactoryTest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/DiactorosFactoryTest.php deleted file mode 100644 index 9d0fc059f..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/DiactorosFactoryTest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; - -use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; - -/** - * @author Kévin Dunglas - * @author Antonio J. García Lagar - * - * @group legacy - */ -class DiactorosFactoryTest extends AbstractHttpMessageFactoryTest -{ - protected function buildHttpMessageFactory(): HttpMessageFactoryInterface - { - if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { - $this->markTestSkipped('Zend Diactoros is not installed.'); - } - - return new DiactorosFactory(); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/HttpFoundationFactoryTest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/HttpFoundationFactoryTest.php deleted file mode 100644 index e35a78930..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/HttpFoundationFactoryTest.php +++ /dev/null @@ -1,272 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; - -use PHPUnit\Framework\TestCase; -use Psr\Http\Message\UploadedFileInterface; -use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; -use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Response; -use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\ServerRequest; -use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Stream; -use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\UploadedFile; -use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Uri; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\File\Exception\FileException; -use Symfony\Component\HttpFoundation\File\UploadedFile as HttpFoundationUploadedFile; - -/** - * @author Kévin Dunglas - */ -class HttpFoundationFactoryTest extends TestCase -{ - /** @var HttpFoundationFactory */ - private $factory; - - /** @var string */ - private $tmpDir; - - public function setUp(): void - { - $this->factory = new HttpFoundationFactory(); - $this->tmpDir = sys_get_temp_dir(); - } - - public function testCreateRequest() - { - $stdClass = new \stdClass(); - $serverRequest = new ServerRequest( - '1.1', - [ - 'X-Dunglas-API-Platform' => '1.0', - 'X-data' => ['a', 'b'], - ], - new Stream('The body'), - '/about/kevin', - 'GET', - 'http://les-tilleuls.coop/about/kevin', - ['country' => 'France'], - ['city' => 'Lille'], - ['url' => 'http://les-tilleuls.coop'], - [ - 'doc1' => $this->createUploadedFile('Doc 1', UPLOAD_ERR_OK, 'doc1.txt', 'text/plain'), - 'nested' => [ - 'docs' => [ - $this->createUploadedFile('Doc 2', UPLOAD_ERR_OK, 'doc2.txt', 'text/plain'), - $this->createUploadedFile('Doc 3', UPLOAD_ERR_OK, 'doc3.txt', 'text/plain'), - ], - ], - ], - ['url' => 'http://dunglas.fr'], - ['custom' => $stdClass] - ); - - $symfonyRequest = $this->factory->createRequest($serverRequest); - $files = $symfonyRequest->files->all(); - - $this->assertEquals('http://les-tilleuls.coop', $symfonyRequest->query->get('url')); - $this->assertEquals('doc1.txt', $files['doc1']->getClientOriginalName()); - $this->assertEquals('doc2.txt', $files['nested']['docs'][0]->getClientOriginalName()); - $this->assertEquals('doc3.txt', $files['nested']['docs'][1]->getClientOriginalName()); - $this->assertEquals('http://dunglas.fr', $symfonyRequest->request->get('url')); - $this->assertEquals($stdClass, $symfonyRequest->attributes->get('custom')); - $this->assertEquals('Lille', $symfonyRequest->cookies->get('city')); - $this->assertEquals('France', $symfonyRequest->server->get('country')); - $this->assertEquals('The body', $symfonyRequest->getContent()); - $this->assertEquals('1.0', $symfonyRequest->headers->get('X-Dunglas-API-Platform')); - $this->assertEquals(['a', 'b'], $symfonyRequest->headers->all('X-data')); - } - - public function testCreateRequestWithStreamedBody() - { - $serverRequest = new ServerRequest( - '1.1', - [], - new Stream('The body'), - '/', - 'GET', - null, - [], - [], - [], - [], - null, - [] - ); - - $symfonyRequest = $this->factory->createRequest($serverRequest, true); - $this->assertEquals('The body', $symfonyRequest->getContent()); - } - - public function testCreateRequestWithNullParsedBody() - { - $serverRequest = new ServerRequest( - '1.1', - [], - new Stream(), - '/', - 'GET', - null, - [], - [], - [], - [], - null, - [] - ); - - $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); - } - - public function testCreateRequestWithObjectParsedBody() - { - $serverRequest = new ServerRequest( - '1.1', - [], - new Stream(), - '/', - 'GET', - null, - [], - [], - [], - [], - new \stdClass(), - [] - ); - - $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); - } - - public function testCreateRequestWithUri() - { - $serverRequest = new ServerRequest( - '1.1', - [], - new Stream(), - '/', - 'GET', - new Uri('http://les-tilleuls.coop/about/kevin'), - [], - [], - [], - [], - null, - [] - ); - - $this->assertEquals('/about/kevin', $this->factory->createRequest($serverRequest)->getPathInfo()); - } - - public function testCreateUploadedFile() - { - $uploadedFile = $this->createUploadedFile('An uploaded file.', UPLOAD_ERR_OK, 'myfile.txt', 'text/plain'); - $symfonyUploadedFile = $this->callCreateUploadedFile($uploadedFile); - $size = $symfonyUploadedFile->getSize(); - - $uniqid = uniqid(); - $symfonyUploadedFile->move($this->tmpDir, $uniqid); - - $this->assertEquals($uploadedFile->getSize(), $size); - $this->assertEquals(UPLOAD_ERR_OK, $symfonyUploadedFile->getError()); - $this->assertEquals('myfile.txt', $symfonyUploadedFile->getClientOriginalName()); - $this->assertEquals('txt', $symfonyUploadedFile->getClientOriginalExtension()); - $this->assertEquals('text/plain', $symfonyUploadedFile->getClientMimeType()); - $this->assertEquals('An uploaded file.', file_get_contents($this->tmpDir.'/'.$uniqid)); - } - - public function testCreateUploadedFileWithError() - { - $this->expectException(FileException::class); - $this->expectExceptionMessage('The file "e" could not be written on disk.'); - - $uploadedFile = $this->createUploadedFile('Error.', UPLOAD_ERR_CANT_WRITE, 'e', 'text/plain'); - $symfonyUploadedFile = $this->callCreateUploadedFile($uploadedFile); - - $this->assertEquals(UPLOAD_ERR_CANT_WRITE, $symfonyUploadedFile->getError()); - - $symfonyUploadedFile->move($this->tmpDir, 'shouldFail.txt'); - } - - private function createUploadedFile($content, $error, $clientFileName, $clientMediaType): UploadedFile - { - $filePath = tempnam($this->tmpDir, uniqid()); - file_put_contents($filePath, $content); - - return new UploadedFile($filePath, filesize($filePath), $error, $clientFileName, $clientMediaType); - } - - private function callCreateUploadedFile(UploadedFileInterface $uploadedFile): HttpFoundationUploadedFile - { - $reflection = new \ReflectionClass($this->factory); - $createUploadedFile = $reflection->getMethod('createUploadedFile'); - $createUploadedFile->setAccessible(true); - - return $createUploadedFile->invokeArgs($this->factory, [$uploadedFile]); - } - - public function testCreateResponse() - { - $response = new Response( - '1.0', - [ - 'X-Symfony' => ['2.8'], - 'Set-Cookie' => [ - 'theme=light', - 'test', - 'ABC=AeD; Domain=dunglas.fr; Path=/kevin; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly; SameSite=Strict', - ], - ], - new Stream('The response body'), - 200 - ); - - $symfonyResponse = $this->factory->createResponse($response); - - $this->assertEquals('1.0', $symfonyResponse->getProtocolVersion()); - $this->assertEquals('2.8', $symfonyResponse->headers->get('X-Symfony')); - - $cookies = $symfonyResponse->headers->getCookies(); - $this->assertEquals('theme', $cookies[0]->getName()); - $this->assertEquals('light', $cookies[0]->getValue()); - $this->assertEquals(0, $cookies[0]->getExpiresTime()); - $this->assertNull($cookies[0]->getDomain()); - $this->assertEquals('/', $cookies[0]->getPath()); - $this->assertFalse($cookies[0]->isSecure()); - $this->assertFalse($cookies[0]->isHttpOnly()); - - $this->assertEquals('test', $cookies[1]->getName()); - $this->assertNull($cookies[1]->getValue()); - - $this->assertEquals('ABC', $cookies[2]->getName()); - $this->assertEquals('AeD', $cookies[2]->getValue()); - $this->assertEquals(strtotime('Wed, 13 Jan 2021 22:23:01 GMT'), $cookies[2]->getExpiresTime()); - $this->assertEquals('dunglas.fr', $cookies[2]->getDomain()); - $this->assertEquals('/kevin', $cookies[2]->getPath()); - $this->assertTrue($cookies[2]->isSecure()); - $this->assertTrue($cookies[2]->isHttpOnly()); - if (\defined('Symfony\Component\HttpFoundation\Cookie::SAMESITE_STRICT')) { - $this->assertEquals(Cookie::SAMESITE_STRICT, $cookies[2]->getSameSite()); - } - - $this->assertEquals('The response body', $symfonyResponse->getContent()); - $this->assertEquals(200, $symfonyResponse->getStatusCode()); - - $symfonyResponse = $this->factory->createResponse($response, true); - - ob_start(); - $symfonyResponse->sendContent(); - $sentContent = ob_get_clean(); - - $this->assertEquals('The response body', $sentContent); - $this->assertEquals(200, $symfonyResponse->getStatusCode()); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/PsrHttpFactoryTest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/PsrHttpFactoryTest.php deleted file mode 100644 index b47cefc18..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Factory/PsrHttpFactoryTest.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; - -use Nyholm\Psr7\Factory\Psr17Factory; -use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; - -/** - * @author Kévin Dunglas - * @author Antonio J. García Lagar - */ -class PsrHttpFactoryTest extends AbstractHttpMessageFactoryTest -{ - protected function buildHttpMessageFactory(): HttpMessageFactoryInterface - { - $factory = new Psr17Factory(); - - return new PsrHttpFactory($factory, $factory, $factory, $factory); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Message.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Message.php deleted file mode 100644 index 0cda6fcb8..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Message.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\MessageInterface; -use Psr\Http\Message\StreamInterface; - -/** - * Message. - * - * @author Kévin Dunglas - */ -class Message implements MessageInterface -{ - private $version = '1.1'; - private $headers = []; - private $body; - - public function __construct($version = '1.1', array $headers = [], StreamInterface $body = null) - { - $this->version = $version; - $this->headers = $headers; - $this->body = null === $body ? new Stream() : $body; - } - - public function getProtocolVersion() - { - return $this->version; - } - - public function withProtocolVersion($version) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getHeaders() - { - return $this->headers; - } - - public function hasHeader($name) - { - return isset($this->headers[$name]); - } - - public function getHeader($name) - { - return $this->hasHeader($name) ? $this->headers[$name] : []; - } - - public function getHeaderLine($name) - { - return $this->hasHeader($name) ? implode(',', $this->headers[$name]) : ''; - } - - public function withHeader($name, $value) - { - $this->headers[$name] = (array) $value; - - return $this; - } - - public function withAddedHeader($name, $value) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withoutHeader($name) - { - unset($this->headers[$name]); - - return $this; - } - - public function getBody() - { - return $this->body; - } - - public function withBody(StreamInterface $body) - { - throw new \BadMethodCallException('Not implemented.'); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Response.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Response.php deleted file mode 100644 index a89079296..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Response.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; - -/** - * @author Kévin Dunglas - */ -class Response extends Message implements ResponseInterface -{ - private $statusCode; - - public function __construct($version = '1.1', array $headers = [], StreamInterface $body = null, $statusCode = 200) - { - parent::__construct($version, $headers, $body); - - $this->statusCode = $statusCode; - } - - public function getStatusCode() - { - return $this->statusCode; - } - - public function withStatus($code, $reasonPhrase = '') - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getReasonPhrase() - { - throw new \BadMethodCallException('Not implemented.'); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/ServerRequest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/ServerRequest.php deleted file mode 100644 index 88ec98434..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/ServerRequest.php +++ /dev/null @@ -1,141 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\StreamInterface; -use Psr\Http\Message\UriInterface; - -/** - * @author Kévin Dunglas - */ -class ServerRequest extends Message implements ServerRequestInterface -{ - private $requestTarget; - private $method; - private $uri; - private $server; - private $cookies; - private $query; - private $uploadedFiles; - private $data; - private $attributes; - - public function __construct($version = '1.1', array $headers = [], StreamInterface $body = null, $requestTarget = '/', $method = 'GET', $uri = null, array $server = [], array $cookies = [], array $query = [], array $uploadedFiles = [], $data = null, array $attributes = []) - { - parent::__construct($version, $headers, $body); - - $this->requestTarget = $requestTarget; - $this->method = $method; - $this->uri = $uri; - $this->server = $server; - $this->cookies = $cookies; - $this->query = $query; - $this->uploadedFiles = $uploadedFiles; - $this->data = $data; - $this->attributes = $attributes; - } - - public function getRequestTarget() - { - return $this->requestTarget; - } - - public function withRequestTarget($requestTarget) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getMethod() - { - return $this->method; - } - - public function withMethod($method) - { - } - - public function getUri() - { - return $this->uri; - } - - public function withUri(UriInterface $uri, $preserveHost = false) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getServerParams() - { - return $this->server; - } - - public function getCookieParams() - { - return $this->cookies; - } - - public function withCookieParams(array $cookies) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getQueryParams() - { - return $this->query; - } - - public function withQueryParams(array $query) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getUploadedFiles() - { - return $this->uploadedFiles; - } - - public function withUploadedFiles(array $uploadedFiles) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getParsedBody() - { - return $this->data; - } - - public function withParsedBody($data) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function getAttributes() - { - return $this->attributes; - } - - public function getAttribute($name, $default = null) - { - return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; - } - - public function withAttribute($name, $value) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withoutAttribute($name) - { - throw new \BadMethodCallException('Not implemented.'); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Stream.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Stream.php deleted file mode 100644 index 06fff284d..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Stream.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\StreamInterface; - -/** - * @author Kévin Dunglas - */ -class Stream implements StreamInterface -{ - private $stringContent; - private $eof = true; - - public function __construct($stringContent = '') - { - $this->stringContent = $stringContent; - } - - public function __toString() - { - return $this->stringContent; - } - - public function close() - { - } - - public function detach() - { - return fopen('data://text/plain,'.$this->stringContent, 'r'); - } - - public function getSize() - { - } - - public function tell() - { - return 0; - } - - public function eof() - { - return $this->eof; - } - - public function isSeekable() - { - return true; - } - - public function seek($offset, $whence = SEEK_SET) - { - } - - public function rewind() - { - $this->eof = false; - } - - public function isWritable() - { - return false; - } - - public function write($string) - { - } - - public function isReadable() - { - return true; - } - - public function read($length) - { - $this->eof = true; - - return $this->stringContent; - } - - public function getContents() - { - return $this->stringContent; - } - - public function getMetadata($key = null) - { - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/UploadedFile.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/UploadedFile.php deleted file mode 100644 index f58a4bd6a..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/UploadedFile.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\UploadedFileInterface; - -/** - * @author Kévin Dunglas - */ -class UploadedFile implements UploadedFileInterface -{ - private $filePath; - private $size; - private $error; - private $clientFileName; - private $clientMediaType; - - public function __construct($filePath, $size = null, $error = UPLOAD_ERR_OK, $clientFileName = null, $clientMediaType = null) - { - $this->filePath = $filePath; - $this->size = $size; - $this->error = $error; - $this->clientFileName = $clientFileName; - $this->clientMediaType = $clientMediaType; - } - - public function getStream() - { - return new Stream(file_get_contents($this->filePath)); - } - - public function moveTo($targetPath) - { - rename($this->filePath, $targetPath); - } - - public function getSize() - { - return $this->size; - } - - public function getError() - { - return $this->error; - } - - public function getClientFilename() - { - return $this->clientFileName; - } - - public function getClientMediaType() - { - return $this->clientMediaType; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Uri.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Uri.php deleted file mode 100644 index f11c7e5b0..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Fixtures/Uri.php +++ /dev/null @@ -1,135 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; - -use Psr\Http\Message\UriInterface; - -/** - * @author Rougin Royce Gutib - */ -class Uri implements UriInterface -{ - private $scheme = ''; - private $userInfo = ''; - private $host = ''; - private $port; - private $path = ''; - private $query = ''; - private $fragment = ''; - private $uriString; - - public function __construct($uri = '') - { - $parts = parse_url($uri); - - $this->scheme = isset($parts['scheme']) ? $parts['scheme'] : ''; - $this->userInfo = isset($parts['user']) ? $parts['user'] : ''; - $this->host = isset($parts['host']) ? $parts['host'] : ''; - $this->port = isset($parts['port']) ? $parts['port'] : null; - $this->path = isset($parts['path']) ? $parts['path'] : ''; - $this->query = isset($parts['query']) ? $parts['query'] : ''; - $this->fragment = isset($parts['fragment']) ? $parts['fragment'] : ''; - $this->uriString = $uri; - } - - public function getScheme() - { - return $this->scheme; - } - - public function getAuthority() - { - if (empty($this->host)) { - return ''; - } - - $authority = $this->host; - - if (!empty($this->userInfo)) { - $authority = $this->userInfo.'@'.$authority; - } - - $authority .= ':'.$this->port; - - return $authority; - } - - public function getUserInfo() - { - return $this->userInfo; - } - - public function getHost() - { - return $this->host; - } - - public function getPort() - { - return $this->port; - } - - public function getPath() - { - return $this->path; - } - - public function getQuery() - { - return $this->query; - } - - public function getFragment() - { - return $this->fragment; - } - - public function withScheme($scheme) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withUserInfo($user, $password = null) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withHost($host) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withPort($port) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withPath($path) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withQuery($query) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function withFragment($fragment) - { - throw new \BadMethodCallException('Not implemented.'); - } - - public function __toString() - { - return $this->uriString; - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Functional/CovertTest.php b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Functional/CovertTest.php deleted file mode 100644 index 137a1541f..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/Tests/Functional/CovertTest.php +++ /dev/null @@ -1,234 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PsrHttpMessage\Tests\Functional; - -use Nyholm\Psr7\Factory\Psr17Factory; -use Nyholm\Psr7\Response as Psr7Response; -use Nyholm\Psr7\ServerRequest as Psr7Request; -use Nyholm\Psr7\Stream as Psr7Stream; -use PHPUnit\Framework\TestCase; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; -use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; -use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; -use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; -use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Test to convert a request/response back and forth to make sure we do not loose data. - * - * @author Tobias Nyholm - */ -class CovertTest extends TestCase -{ - private $tmpDir; - - public function setUp(): void - { - if (!class_exists('Nyholm\Psr7\ServerRequest')) { - $this->markTestSkipped('nyholm/psr7 is not installed.'); - } - - $this->tmpDir = sys_get_temp_dir(); - } - - /** - * @dataProvider requestProvider - * - * @param Request|ServerRequestInterface $request - * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $firstFactory - * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $secondFactory - */ - public function testConvertRequestMultipleTimes($request, $firstFactory, $secondFactory) - { - $temporaryRequest = $firstFactory->createRequest($request); - $finalRequest = $secondFactory->createRequest($temporaryRequest); - - if ($finalRequest instanceof Request) { - $this->assertEquals($request->getBasePath(), $finalRequest->getBasePath()); - $this->assertEquals($request->getBaseUrl(), $finalRequest->getBaseUrl()); - $this->assertEquals($request->getContent(), $finalRequest->getContent()); - $this->assertEquals($request->getEncodings(), $finalRequest->getEncodings()); - $this->assertEquals($request->getETags(), $finalRequest->getETags()); - $this->assertEquals($request->getHost(), $finalRequest->getHost()); - $this->assertEquals($request->getHttpHost(), $finalRequest->getHttpHost()); - $this->assertEquals($request->getMethod(), $finalRequest->getMethod()); - $this->assertEquals($request->getPassword(), $finalRequest->getPassword()); - $this->assertEquals($request->getPathInfo(), $finalRequest->getPathInfo()); - $this->assertEquals($request->getPort(), $finalRequest->getPort()); - $this->assertEquals($request->getProtocolVersion(), $finalRequest->getProtocolVersion()); - $this->assertEquals($request->getQueryString(), $finalRequest->getQueryString()); - $this->assertEquals($request->getRequestUri(), $finalRequest->getRequestUri()); - $this->assertEquals($request->getScheme(), $finalRequest->getScheme()); - $this->assertEquals($request->getSchemeAndHttpHost(), $finalRequest->getSchemeAndHttpHost()); - $this->assertEquals($request->getScriptName(), $finalRequest->getScriptName()); - $this->assertEquals($request->getUri(), $finalRequest->getUri()); - $this->assertEquals($request->getUser(), $finalRequest->getUser()); - $this->assertEquals($request->getUserInfo(), $finalRequest->getUserInfo()); - } elseif ($finalRequest instanceof ServerRequestInterface) { - $strToLower = function ($arr) { - foreach ($arr as $key => $value) { - yield strtolower($key) => $value; - } - }; - $this->assertEquals($request->getAttributes(), $finalRequest->getAttributes()); - $this->assertEquals($request->getCookieParams(), $finalRequest->getCookieParams()); - $this->assertEquals((array) $request->getParsedBody(), (array) $finalRequest->getParsedBody()); - $this->assertEquals($request->getQueryParams(), $finalRequest->getQueryParams()); - // PSR7 does not define a "withServerParams" so this is impossible to implement without knowing the PSR7 implementation. - //$this->assertEquals($request->getServerParams(), $finalRequest->getServerParams()); - $this->assertEquals($request->getUploadedFiles(), $finalRequest->getUploadedFiles()); - $this->assertEquals($request->getMethod(), $finalRequest->getMethod()); - $this->assertEquals($request->getRequestTarget(), $finalRequest->getRequestTarget()); - $this->assertEquals((string) $request->getUri(), (string) $finalRequest->getUri()); - $this->assertEquals((string) $request->getBody(), (string) $finalRequest->getBody()); - $this->assertEquals($strToLower($request->getHeaders()), $strToLower($finalRequest->getHeaders())); - $this->assertEquals($request->getProtocolVersion(), $finalRequest->getProtocolVersion()); - } else { - $this->fail('$finalRequest must be an instance of PSR7 or a HTTPFoundation request'); - } - } - - public function requestProvider() - { - $sfRequest = new Request( - [ - 'foo' => '1', - 'bar' => ['baz' => '42'], - ], - [ - 'twitter' => [ - '@dunglas' => 'Kévin Dunglas', - '@coopTilleuls' => 'Les-Tilleuls.coop', - ], - 'baz' => '2', - ], - [ - 'a2' => ['foo' => 'bar'], - ], - [ - 'c1' => 'foo', - 'c2' => ['c3' => 'bar'], - ], - [ - 'f1' => $this->createUploadedFile('F1', 'f1.txt', 'text/plain', UPLOAD_ERR_OK), - 'foo' => ['f2' => $this->createUploadedFile('F2', 'f2.txt', 'text/plain', UPLOAD_ERR_OK)], - ], - [ - 'REQUEST_METHOD' => 'POST', - 'HTTP_HOST' => 'dunglas.fr', - 'SERVER_NAME' => 'dunglas.fr', - 'SERVER_PORT' => null, - 'HTTP_X_SYMFONY' => '2.8', - 'REQUEST_URI' => '/testCreateRequest?bar[baz]=42&foo=1', - 'QUERY_STRING' => 'foo=1&bar[baz]=42', - ], - 'Content' - ); - - $psr7Request = (new Psr7Request('POST', 'http://tnyholm.se/foo/?bar=biz')) - ->withQueryParams(['bar' => 'biz']); - - $nyholmFactory = new Psr17Factory(); - $psr17Factory = new PsrHttpFactory($nyholmFactory, $nyholmFactory, $nyholmFactory, $nyholmFactory); - $symfonyFactory = new HttpFoundationFactory(); - - return [ - [$sfRequest, $psr17Factory, $symfonyFactory], - [$psr7Request, $symfonyFactory, $psr17Factory], - ]; - } - - /** - * @dataProvider responseProvider - * - * @param Response|ResponseInterface $response - * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $firstFactory - * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $secondFactory - */ - public function testConvertResponseMultipleTimes($response, $firstFactory, $secondFactory) - { - $temporaryResponse = $firstFactory->createResponse($response); - $finalResponse = $secondFactory->createResponse($temporaryResponse); - - if ($finalResponse instanceof Response) { - $this->assertEquals($response->getAge(), $finalResponse->getAge()); - $this->assertEquals($response->getCharset(), $finalResponse->getCharset()); - $this->assertEquals($response->getContent(), $finalResponse->getContent()); - $this->assertEquals($response->getDate(), $finalResponse->getDate()); - $this->assertEquals($response->getEtag(), $finalResponse->getEtag()); - $this->assertEquals($response->getExpires(), $finalResponse->getExpires()); - $this->assertEquals($response->getLastModified(), $finalResponse->getLastModified()); - $this->assertEquals($response->getMaxAge(), $finalResponse->getMaxAge()); - $this->assertEquals($response->getProtocolVersion(), $finalResponse->getProtocolVersion()); - $this->assertEquals($response->getStatusCode(), $finalResponse->getStatusCode()); - $this->assertEquals($response->getTtl(), $finalResponse->getTtl()); - } elseif ($finalResponse instanceof ResponseInterface) { - $strToLower = function ($arr) { - foreach ($arr as $key => $value) { - yield strtolower($key) => $value; - } - }; - $this->assertEquals($response->getStatusCode(), $finalResponse->getStatusCode()); - $this->assertEquals($response->getReasonPhrase(), $finalResponse->getReasonPhrase()); - $this->assertEquals((string) $response->getBody(), (string) $finalResponse->getBody()); - $this->assertEquals($strToLower($response->getHeaders()), $strToLower($finalResponse->getHeaders())); - $this->assertEquals($response->getProtocolVersion(), $finalResponse->getProtocolVersion()); - } else { - $this->fail('$finalResponse must be an instance of PSR7 or a HTTPFoundation response'); - } - } - - public function responseProvider() - { - $sfResponse = new Response( - 'Response content.', - 202, - ['x-symfony' => ['3.4']] - ); - - if (method_exists(Cookie::class, 'create')) { - $cookie = Cookie::create('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT')); - } else { - $cookie = new Cookie('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT')); - } - - $sfResponse->headers->setCookie($cookie); - $body = Psr7Stream::create(); - $status = 302; - $headers = [ - 'location' => ['http://example.com/'], - ]; - $zendResponse = new Psr7Response($status, $headers, $body); - - $nyholmFactory = new Psr17Factory(); - $psr17Factory = new PsrHttpFactory($nyholmFactory, $nyholmFactory, $nyholmFactory, $nyholmFactory); - $symfonyFactory = new HttpFoundationFactory(); - - return [ - [$sfResponse, $psr17Factory, $symfonyFactory], - [$zendResponse, $symfonyFactory, $psr17Factory], - ]; - } - - private function createUploadedFile($content, $originalName, $mimeType, $error) - { - $path = tempnam($this->tmpDir, uniqid()); - file_put_contents($path, $content); - - return new UploadedFile($path, $originalName, $mimeType, $error, true); - } -} diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/composer.json b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/composer.json index 07ed9cfe0..b705eb2e2 100644 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/composer.json +++ b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/composer.json @@ -16,14 +16,20 @@ } ], "require": { - "php": "^7.1", - "psr/http-message": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.0" + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.0", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2", "nyholm/psr7": "^1.1", - "zendframework/zend-diactoros": "^1.4.1 || ^2.0" + "psr/log": "^1.1 || ^2 || ^3" }, "suggest": { "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" @@ -36,7 +42,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-main": "2.3-dev" } } } diff --git a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/phpunit.xml.dist b/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/phpunit.xml.dist deleted file mode 100644 index 43aeaa338..000000000 --- a/lam/lib/3rdParty/composer/symfony/psr-http-message-bridge/phpunit.xml.dist +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - ./Tests/ - - - - - - ./ - - ./Resources - ./Tests - ./vendor - - - - diff --git a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceLocatorTrait.php b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceLocatorTrait.php index 74dfa4362..19d3e80ff 100644 --- a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceLocatorTrait.php +++ b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceLocatorTrait.php @@ -26,9 +26,9 @@ class_exists(NotFoundExceptionInterface::class); */ trait ServiceLocatorTrait { - private $factories; - private $loading = []; - private $providedTypes; + private array $factories; + private array $loading = []; + private array $providedTypes; /** * @param callable[] $factories @@ -40,20 +40,16 @@ public function __construct(array $factories) /** * {@inheritdoc} - * - * @return bool */ - public function has(string $id) + public function has(string $id): bool { return isset($this->factories[$id]); } /** * {@inheritdoc} - * - * @return mixed */ - public function get(string $id) + public function get(string $id): mixed { if (!isset($this->factories[$id])) { throw $this->createNotFoundException($id); @@ -80,7 +76,7 @@ public function get(string $id) */ public function getProvidedServices(): array { - if (null === $this->providedTypes) { + if (!isset($this->providedTypes)) { $this->providedTypes = []; foreach ($this->factories as $name => $factory) { diff --git a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberInterface.php b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberInterface.php index 098ab908c..881ab971a 100644 --- a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberInterface.php +++ b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberInterface.php @@ -49,5 +49,5 @@ interface ServiceSubscriberInterface * * @return string[] The required service types, optionally keyed by service names */ - public static function getSubscribedServices(); + public static function getSubscribedServices(): array; } diff --git a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberTrait.php b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberTrait.php index 16e3eb2c1..ee9d9d9dd 100644 --- a/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberTrait.php +++ b/lam/lib/3rdParty/composer/symfony/service-contracts/ServiceSubscriberTrait.php @@ -31,61 +31,31 @@ trait ServiceSubscriberTrait public static function getSubscribedServices(): array { $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; - $attributeOptIn = false; - if (\PHP_VERSION_ID >= 80000) { - foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { - if (self::class !== $method->getDeclaringClass()->name) { - continue; - } - - if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { - continue; - } - - 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)); - } - - 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)); - } - - $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; - - if ($returnType->allowsNull()) { - $serviceId = '?'.$serviceId; - } - - $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId; - $attributeOptIn = true; + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; } - } - - if (!$attributeOptIn) { - foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { - if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { - continue; - } - if (self::class !== $method->getDeclaringClass()->name) { - continue; - } + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } - if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) { - continue; - } + 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)); + } - if ($returnType->isBuiltin()) { - continue; - } + 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)); + } - if (\PHP_VERSION_ID >= 80000) { - trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class); - } + $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; - $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType); + if ($returnType->allowsNull()) { + $serviceId = '?'.$serviceId; } + + $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId; } return $services; @@ -93,10 +63,8 @@ public static function getSubscribedServices(): array /** * @required - * - * @return ContainerInterface|null */ - public function setContainer(ContainerInterface $container) + public function setContainer(ContainerInterface $container): ?ContainerInterface { $this->container = $container; diff --git a/lam/lib/3rdParty/composer/symfony/service-contracts/Test/ServiceLocatorTest.php b/lam/lib/3rdParty/composer/symfony/service-contracts/Test/ServiceLocatorTest.php index 2a1b565f5..88f6a0687 100644 --- a/lam/lib/3rdParty/composer/symfony/service-contracts/Test/ServiceLocatorTest.php +++ b/lam/lib/3rdParty/composer/symfony/service-contracts/Test/ServiceLocatorTest.php @@ -17,10 +17,7 @@ abstract class ServiceLocatorTest extends TestCase { - /** - * @return ContainerInterface - */ - protected function getServiceLocator(array $factories) + protected function getServiceLocator(array $factories): ContainerInterface { return new class($factories) implements ContainerInterface { use ServiceLocatorTrait; diff --git a/lam/lib/3rdParty/composer/symfony/service-contracts/composer.json b/lam/lib/3rdParty/composer/symfony/service-contracts/composer.json index f05863701..d3b047f9a 100644 --- a/lam/lib/3rdParty/composer/symfony/service-contracts/composer.json +++ b/lam/lib/3rdParty/composer/symfony/service-contracts/composer.json @@ -16,9 +16,8 @@ } ], "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.0.2", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -32,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lam/lib/3rdParty/composer/symfony/translation-contracts/LocaleAwareInterface.php b/lam/lib/3rdParty/composer/symfony/translation-contracts/LocaleAwareInterface.php index 693f92ba9..6923b977e 100644 --- a/lam/lib/3rdParty/composer/symfony/translation-contracts/LocaleAwareInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation-contracts/LocaleAwareInterface.php @@ -16,16 +16,12 @@ interface LocaleAwareInterface /** * Sets the current locale. * - * @param string $locale The locale - * * @throws \InvalidArgumentException If the locale contains invalid characters */ public function setLocale(string $locale); /** * Returns the current locale. - * - * @return string */ - public function getLocale(); + public function getLocale(): string; } diff --git a/lam/lib/3rdParty/composer/symfony/translation-contracts/Test/TranslatorTest.php b/lam/lib/3rdParty/composer/symfony/translation-contracts/Test/TranslatorTest.php index a3e9b20af..4e5999df4 100644 --- a/lam/lib/3rdParty/composer/symfony/translation-contracts/Test/TranslatorTest.php +++ b/lam/lib/3rdParty/composer/symfony/translation-contracts/Test/TranslatorTest.php @@ -43,10 +43,7 @@ protected function tearDown(): void \Locale::setDefault($this->defaultLocale); } - /** - * @return TranslatorInterface - */ - public function getTranslator() + public function getTranslator(): TranslatorInterface { return new class() implements TranslatorInterface { use TranslatorTrait; @@ -317,10 +314,8 @@ public function testLangcodes($nplural, $langCodes) * This array should contain all currently known langcodes. * * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete. - * - * @return array */ - public function successLangcodes() + public function successLangcodes(): array { return [ ['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']], @@ -339,7 +334,7 @@ public function successLangcodes() * * @return array with nplural together with langcodes */ - public function failingLangcodes() + public function failingLangcodes(): array { return [ ['1', ['fa']], @@ -353,11 +348,10 @@ public function failingLangcodes() /** * We validate only on the plural coverage. Thus the real rules is not tested. * - * @param string $nplural Plural expected - * @param array $matrix Containing langcodes and their plural index values - * @param bool $expectSuccess + * @param string $nplural Plural expected + * @param array $matrix Containing langcodes and their plural index values */ - protected function validateMatrix($nplural, $matrix, $expectSuccess = true) + protected function validateMatrix(string $nplural, array $matrix, bool $expectSuccess = true) { foreach ($matrix as $langCode => $data) { $indexes = array_flip($data); diff --git a/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorInterface.php b/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorInterface.php index 77b7a9c58..018db07eb 100644 --- a/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorInterface.php @@ -13,8 +13,6 @@ /** * @author Fabien Potencier - * - * @method string getLocale() Returns the default locale */ interface TranslatorInterface { @@ -59,9 +57,12 @@ interface TranslatorInterface * @param string|null $domain The domain for the message or null to use the default * @param string|null $locale The locale or null to use the default * - * @return string - * * @throws \InvalidArgumentException If the locale contains invalid characters */ - public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null); + public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string; + + /** + * Returns the default locale. + */ + public function getLocale(): string; } diff --git a/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorTrait.php b/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorTrait.php index 405ce8d70..9c264bd29 100644 --- a/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorTrait.php +++ b/lam/lib/3rdParty/composer/symfony/translation-contracts/TranslatorTrait.php @@ -20,7 +20,7 @@ */ trait TranslatorTrait { - private $locale; + private ?string $locale = null; /** * {@inheritdoc} @@ -32,10 +32,8 @@ public function setLocale(string $locale) /** * {@inheritdoc} - * - * @return string */ - public function getLocale() + public function getLocale(): string { return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en'); } diff --git a/lam/lib/3rdParty/composer/symfony/translation-contracts/composer.json b/lam/lib/3rdParty/composer/symfony/translation-contracts/composer.json index 65fe243a4..875242f6d 100644 --- a/lam/lib/3rdParty/composer/symfony/translation-contracts/composer.json +++ b/lam/lib/3rdParty/composer/symfony/translation-contracts/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.2.5" + "php": ">=8.0.2" }, "suggest": { "symfony/translation-implementation": "" @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lam/lib/3rdParty/composer/symfony/translation/CHANGELOG.md b/lam/lib/3rdParty/composer/symfony/translation/CHANGELOG.md index 93615dcac..160b5e694 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/symfony/translation/CHANGELOG.md @@ -1,13 +1,6 @@ CHANGELOG ========= -5.4.21 ------- - - * [BC BREAK] The following data providers for `ProviderFactoryTestCase` are now static: - `supportsProvider()`, `createProvider()`, `unsupportedSchemeProvider()`and `incompleteDsnProvider()` - * [BC BREAK] `ProviderTestCase::toStringProvider()` is now static - 5.4 --- diff --git a/lam/lib/3rdParty/composer/symfony/translation/Catalogue/AbstractOperation.php b/lam/lib/3rdParty/composer/symfony/translation/Catalogue/AbstractOperation.php index 98d42e5b6..43a52fab2 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Catalogue/AbstractOperation.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Catalogue/AbstractOperation.php @@ -80,7 +80,7 @@ public function __construct(MessageCatalogueInterface $source, MessageCatalogueI /** * {@inheritdoc} */ - public function getDomains() + public function getDomains(): array { if (null === $this->domains) { $domains = []; @@ -103,7 +103,7 @@ public function getDomains() /** * {@inheritdoc} */ - public function getMessages(string $domain) + public function getMessages(string $domain): array { if (!\in_array($domain, $this->getDomains())) { throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); @@ -119,7 +119,7 @@ public function getMessages(string $domain) /** * {@inheritdoc} */ - public function getNewMessages(string $domain) + public function getNewMessages(string $domain): array { if (!\in_array($domain, $this->getDomains())) { throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); @@ -135,7 +135,7 @@ public function getNewMessages(string $domain) /** * {@inheritdoc} */ - public function getObsoleteMessages(string $domain) + public function getObsoleteMessages(string $domain): array { if (!\in_array($domain, $this->getDomains())) { throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); @@ -151,7 +151,7 @@ public function getObsoleteMessages(string $domain) /** * {@inheritdoc} */ - public function getResult() + public function getResult(): MessageCatalogueInterface { foreach ($this->getDomains() as $domain) { if (!isset($this->messages[$domain])) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Catalogue/OperationInterface.php b/lam/lib/3rdParty/composer/symfony/translation/Catalogue/OperationInterface.php index 9ffac88d2..1fe9534e8 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Catalogue/OperationInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Catalogue/OperationInterface.php @@ -36,36 +36,26 @@ interface OperationInterface { /** * Returns domains affected by operation. - * - * @return array */ - public function getDomains(); + public function getDomains(): array; /** * Returns all valid messages ('all') after operation. - * - * @return array */ - public function getMessages(string $domain); + public function getMessages(string $domain): array; /** * Returns new messages ('new') after operation. - * - * @return array */ - public function getNewMessages(string $domain); + public function getNewMessages(string $domain): array; /** * Returns obsolete messages ('obsolete') after operation. - * - * @return array */ - public function getObsoleteMessages(string $domain); + public function getObsoleteMessages(string $domain): array; /** * Returns resulting catalogue ('result'). - * - * @return MessageCatalogueInterface */ - public function getResult(); + public function getResult(): MessageCatalogueInterface; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPullCommand.php b/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPullCommand.php index e2e7c00dc..f30e64d78 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPullCommand.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPullCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Translation\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Completion\CompletionInput; use Symfony\Component\Console\Completion\CompletionSuggestions; @@ -28,19 +29,17 @@ /** * @author Mathieu Santostefano */ +#[AsCommand(name: 'translation:pull', description: 'Pull translations from a given provider.')] final class TranslationPullCommand extends Command { use TranslationTrait; - protected static $defaultName = 'translation:pull'; - protected static $defaultDescription = 'Pull translations from a given provider.'; - private $providerCollection; private $writer; private $reader; - private $defaultLocale; - private $transPaths; - private $enabledLocales; + private string $defaultLocale; + private array $transPaths; + private array $enabledLocales; public function __construct(TranslationProviderCollection $providerCollection, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, array $transPaths = [], array $enabledLocales = []) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPushCommand.php b/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPushCommand.php index bf6e8c948..795e68c13 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPushCommand.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Command/TranslationPushCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Translation\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Completion\CompletionInput; use Symfony\Component\Console\Completion\CompletionSuggestions; @@ -28,17 +29,15 @@ /** * @author Mathieu Santostefano */ +#[AsCommand(name: 'translation:push', description: 'Push translations to a given provider.')] final class TranslationPushCommand extends Command { use TranslationTrait; - protected static $defaultName = 'translation:push'; - protected static $defaultDescription = 'Push translations to a given provider.'; - private $providers; private $reader; - private $transPaths; - private $enabledLocales; + private array $transPaths; + private array $enabledLocales; public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = []) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Command/XliffLintCommand.php b/lam/lib/3rdParty/composer/symfony/translation/Command/XliffLintCommand.php index fb2b5f31c..f062fb79f 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Command/XliffLintCommand.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Command/XliffLintCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Translation\Command; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\CI\GithubActionReporter; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Completion\CompletionInput; @@ -31,23 +32,21 @@ * @author Robin Chalas * @author Javier Eguiluz */ +#[AsCommand(name: 'lint:xliff', description: 'Lint an XLIFF file and outputs encountered errors')] class XliffLintCommand extends Command { - protected static $defaultName = 'lint:xliff'; - protected static $defaultDescription = 'Lint an XLIFF file and outputs encountered errors'; - - private $format; - private $displayCorrectFiles; - private $directoryIteratorProvider; - private $isReadableProvider; - private $requireStrictFileNames; + private string $format; + private bool $displayCorrectFiles; + private ?\Closure $directoryIteratorProvider; + private ?\Closure $isReadableProvider; + private bool $requireStrictFileNames; public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true) { parent::__construct($name); - $this->directoryIteratorProvider = $directoryIteratorProvider; - $this->isReadableProvider = $isReadableProvider; + $this->directoryIteratorProvider = null === $directoryIteratorProvider || $directoryIteratorProvider instanceof \Closure ? $directoryIteratorProvider : \Closure::fromCallable($directoryIteratorProvider); + $this->isReadableProvider = null === $isReadableProvider || $isReadableProvider instanceof \Closure ? $isReadableProvider : \Closure::fromCallable($isReadableProvider); $this->requireStrictFileNames = $requireStrictFileNames; } @@ -57,7 +56,6 @@ public function __construct(string $name = null, callable $directoryIteratorProv protected function configure() { $this - ->setDescription(self::$defaultDescription) ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format') ->setHelp(<<getArgument('filename'); diff --git a/lam/lib/3rdParty/composer/symfony/translation/DataCollector/TranslationDataCollector.php b/lam/lib/3rdParty/composer/symfony/translation/DataCollector/TranslationDataCollector.php index 379130a44..0f7901d52 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DataCollector/TranslationDataCollector.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DataCollector/TranslationDataCollector.php @@ -62,10 +62,7 @@ public function reset() $this->data = []; } - /** - * @return array|Data - */ - public function getMessages() + public function getMessages(): array|Data { return $this->data['messages'] ?? []; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/DataCollectorTranslator.php b/lam/lib/3rdParty/composer/symfony/translation/DataCollectorTranslator.php index ea5a2dd5e..2a08b0960 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DataCollectorTranslator.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DataCollectorTranslator.php @@ -26,7 +26,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter public const MESSAGE_EQUALS_FALLBACK = 2; private $translator; - private $messages = []; + private array $messages = []; /** * @param TranslatorInterface&TranslatorBagInterface&LocaleAwareInterface $translator @@ -43,7 +43,7 @@ public function __construct(TranslatorInterface $translator) /** * {@inheritdoc} */ - public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null) + public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string { $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale); $this->collectMessage($locale, $domain, $id, $trans, $parameters); @@ -62,7 +62,7 @@ public function setLocale(string $locale) /** * {@inheritdoc} */ - public function getLocale() + public function getLocale(): string { return $this->translator->getLocale(); } @@ -70,7 +70,7 @@ public function getLocale() /** * {@inheritdoc} */ - public function getCatalogue(string $locale = null) + public function getCatalogue(string $locale = null): MessageCatalogueInterface { return $this->translator->getCatalogue($locale); } @@ -88,7 +88,7 @@ public function getCatalogues(): array * * @return string[] */ - public function warmUp(string $cacheDir) + public function warmUp(string $cacheDir): array { if ($this->translator instanceof WarmableInterface) { return (array) $this->translator->warmUp($cacheDir); @@ -99,10 +99,8 @@ public function warmUp(string $cacheDir) /** * Gets the fallback locales. - * - * @return array */ - public function getFallbackLocales() + public function getFallbackLocales(): array { if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) { return $this->translator->getFallbackLocales(); @@ -119,10 +117,7 @@ public function __call(string $method, array $args) return $this->translator->{$method}(...$args); } - /** - * @return array - */ - public function getCollectedMessages() + public function getCollectedMessages(): array { return $this->messages; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationDumperPass.php b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationDumperPass.php index 6d78342bc..4020a0788 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationDumperPass.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationDumperPass.php @@ -20,28 +20,15 @@ */ class TranslationDumperPass implements CompilerPassInterface { - private $writerServiceId; - private $dumperTag; - - public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper') - { - if (1 < \func_num_args()) { - trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->writerServiceId = $writerServiceId; - $this->dumperTag = $dumperTag; - } - public function process(ContainerBuilder $container) { - if (!$container->hasDefinition($this->writerServiceId)) { + if (!$container->hasDefinition('translation.writer')) { return; } - $definition = $container->getDefinition($this->writerServiceId); + $definition = $container->getDefinition('translation.writer'); - foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) { + foreach ($container->findTaggedServiceIds('translation.dumper', true) as $id => $attributes) { $definition->addMethodCall('addDumper', [$attributes[0]['alias'], new Reference($id)]); } } diff --git a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationExtractorPass.php b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationExtractorPass.php index fab6b20ae..ee7c47ae4 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationExtractorPass.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslationExtractorPass.php @@ -21,28 +21,15 @@ */ class TranslationExtractorPass implements CompilerPassInterface { - private $extractorServiceId; - private $extractorTag; - - public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor') - { - if (0 < \func_num_args()) { - trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->extractorServiceId = $extractorServiceId; - $this->extractorTag = $extractorTag; - } - public function process(ContainerBuilder $container) { - if (!$container->hasDefinition($this->extractorServiceId)) { + if (!$container->hasDefinition('translation.extractor')) { return; } - $definition = $container->getDefinition($this->extractorServiceId); + $definition = $container->getDefinition('translation.extractor'); - foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) { + foreach ($container->findTaggedServiceIds('translation.extractor', true) as $id => $attributes) { if (!isset($attributes[0]['alias'])) { throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id)); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPass.php b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPass.php index e6a4b362f..be79cdaf0 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPass.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPass.php @@ -18,34 +18,15 @@ class TranslatorPass implements CompilerPassInterface { - private $translatorServiceId; - private $readerServiceId; - private $loaderTag; - private $debugCommandServiceId; - private $updateCommandServiceId; - - public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_extract') - { - if (0 < \func_num_args()) { - trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->translatorServiceId = $translatorServiceId; - $this->readerServiceId = $readerServiceId; - $this->loaderTag = $loaderTag; - $this->debugCommandServiceId = $debugCommandServiceId; - $this->updateCommandServiceId = $updateCommandServiceId; - } - public function process(ContainerBuilder $container) { - if (!$container->hasDefinition($this->translatorServiceId)) { + if (!$container->hasDefinition('translator.default')) { return; } $loaders = []; $loaderRefs = []; - foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) { + foreach ($container->findTaggedServiceIds('translation.loader', true) as $id => $attributes) { $loaderRefs[$id] = new Reference($id); $loaders[$id][] = $attributes[0]['alias']; if (isset($attributes[0]['legacy-alias'])) { @@ -53,8 +34,8 @@ public function process(ContainerBuilder $container) } } - if ($container->hasDefinition($this->readerServiceId)) { - $definition = $container->getDefinition($this->readerServiceId); + if ($container->hasDefinition('translation.reader')) { + $definition = $container->getDefinition('translation.reader'); foreach ($loaders as $id => $formats) { foreach ($formats as $format) { $definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]); @@ -63,7 +44,7 @@ public function process(ContainerBuilder $container) } $container - ->findDefinition($this->translatorServiceId) + ->findDefinition('translator.default') ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs)) ->replaceArgument(3, $loaders) ; @@ -73,16 +54,16 @@ public function process(ContainerBuilder $container) } $paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(1)); - if ($container->hasDefinition($this->debugCommandServiceId)) { - $definition = $container->getDefinition($this->debugCommandServiceId); + if ($container->hasDefinition('console.command.translation_debug')) { + $definition = $container->getDefinition('console.command.translation_debug'); $definition->replaceArgument(4, $container->getParameter('twig.default_path')); if (\count($definition->getArguments()) > 6) { $definition->replaceArgument(6, $paths); } } - if ($container->hasDefinition($this->updateCommandServiceId)) { - $definition = $container->getDefinition($this->updateCommandServiceId); + if ($container->hasDefinition('console.command.translation_extract')) { + $definition = $container->getDefinition('console.command.translation_extract'); $definition->replaceArgument(5, $container->getParameter('twig.default_path')); if (\count($definition->getArguments()) > 7) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPathsPass.php b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPathsPass.php index 2ee13640c..b85c06621 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPathsPass.php +++ b/lam/lib/3rdParty/composer/symfony/translation/DependencyInjection/TranslatorPathsPass.php @@ -16,49 +16,32 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; -use Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver; /** * @author Yonel Ceruto */ class TranslatorPathsPass extends AbstractRecursivePass { - private $translatorServiceId; - private $debugCommandServiceId; - private $updateCommandServiceId; - private $resolverServiceId; - private $level = 0; + private int $level = 0; /** * @var array */ - private $paths = []; + private array $paths = []; /** * @var array */ - private $definitions = []; + private array $definitions = []; /** * @var array> */ - private $controllers = []; - - public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_extract', string $resolverServiceId = 'argument_resolver.service') - { - if (0 < \func_num_args()) { - trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->translatorServiceId = $translatorServiceId; - $this->debugCommandServiceId = $debugCommandServiceId; - $this->updateCommandServiceId = $updateCommandServiceId; - $this->resolverServiceId = $resolverServiceId; - } + private array $controllers = []; public function process(ContainerBuilder $container) { - if (!$container->hasDefinition($this->translatorServiceId)) { + if (!$container->hasDefinition('translator')) { return; } @@ -83,12 +66,12 @@ public function process(ContainerBuilder $container) } } if ($paths) { - if ($container->hasDefinition($this->debugCommandServiceId)) { - $definition = $container->getDefinition($this->debugCommandServiceId); + if ($container->hasDefinition('console.command.translation_debug')) { + $definition = $container->getDefinition('console.command.translation_debug'); $definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths)); } - if ($container->hasDefinition($this->updateCommandServiceId)) { - $definition = $container->getDefinition($this->updateCommandServiceId); + if ($container->hasDefinition('console.command.translation_extract')) { + $definition = $container->getDefinition('console.command.translation_extract'); $definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths)); } } @@ -99,10 +82,10 @@ public function process(ContainerBuilder $container) } } - protected function processValue($value, bool $isRoot = false) + protected function processValue(mixed $value, bool $isRoot = false): mixed { if ($value instanceof Reference) { - if ((string) $value === $this->translatorServiceId) { + if ('translator' === (string) $value) { for ($i = $this->level - 1; $i >= 0; --$i) { $class = $this->definitions[$i]->getClass(); @@ -137,20 +120,28 @@ protected function processValue($value, bool $isRoot = false) private function findControllerArguments(ContainerBuilder $container): array { - if (!$container->has($this->resolverServiceId)) { - return []; - } - $resolverDef = $container->findDefinition($this->resolverServiceId); + if ($container->hasDefinition('argument_resolver.service')) { + $argument = $container->getDefinition('argument_resolver.service')->getArgument(0); + if ($argument instanceof Reference) { + $argument = $container->getDefinition($argument); + } - if (TraceableValueResolver::class === $resolverDef->getClass()) { - $resolverDef = $container->getDefinition($resolverDef->getArgument(0)); + return $argument->getArgument(0); } - $argument = $resolverDef->getArgument(0); - if ($argument instanceof Reference) { - $argument = $container->getDefinition($argument); + if ($container->hasDefinition('debug.'.'argument_resolver.service')) { + $argument = $container->getDefinition('debug.'.'argument_resolver.service')->getArgument(0); + if ($argument instanceof Reference) { + $argument = $container->getDefinition($argument); + } + $argument = $argument->getArgument(0); + if ($argument instanceof Reference) { + $argument = $container->getDefinition($argument); + } + + return $argument->getArgument(0); } - return $argument->getArgument(0); + return []; } } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/CsvFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/CsvFileDumper.php index 0c8589af8..0bd3f5e0f 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/CsvFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/CsvFileDumper.php @@ -20,13 +20,13 @@ */ class CsvFileDumper extends FileDumper { - private $delimiter = ';'; - private $enclosure = '"'; + private string $delimiter = ';'; + private string $enclosure = '"'; /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $handle = fopen('php://memory', 'r+'); @@ -53,7 +53,7 @@ public function setCsvControl(string $delimiter = ';', string $enclosure = '"') /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'csv'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/FileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/FileDumper.php index 0e1084519..6bad4ff32 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/FileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/FileDumper.php @@ -86,17 +86,13 @@ public function dump(MessageCatalogue $messages, array $options = []) /** * Transforms a domain of a message catalogue to its string representation. - * - * @return string */ - abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []); + abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string; /** * Gets the file extension of the dumper. - * - * @return string */ - abstract protected function getExtension(); + abstract protected function getExtension(): string; /** * Gets the relative file path using the template. diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/IcuResFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/IcuResFileDumper.php index 12a7a8cfc..f13f86c80 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/IcuResFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/IcuResFileDumper.php @@ -28,7 +28,7 @@ class IcuResFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $data = $indexes = $resources = ''; @@ -97,7 +97,7 @@ private function getPosition(string $data) /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'res'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/IniFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/IniFileDumper.php index 93c900a4a..75032be14 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/IniFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/IniFileDumper.php @@ -23,7 +23,7 @@ class IniFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $output = ''; @@ -38,7 +38,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'ini'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/JsonFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/JsonFileDumper.php index 34c0b5694..11027303a 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/JsonFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/JsonFileDumper.php @@ -23,7 +23,7 @@ class JsonFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $flags = $options['json_encoding'] ?? \JSON_PRETTY_PRINT; @@ -33,7 +33,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'json'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/MoFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/MoFileDumper.php index f52206ee3..1ea546275 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/MoFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/MoFileDumper.php @@ -24,7 +24,7 @@ class MoFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $sources = $targets = $sourceOffsets = $targetOffsets = ''; $offsets = []; @@ -70,12 +70,12 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'mo'; } - private function writeLong($str): string + private function writeLong(mixed $str): string { return pack('V*', $str); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/PhpFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/PhpFileDumper.php index 6163b5297..565d89375 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/PhpFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/PhpFileDumper.php @@ -23,7 +23,7 @@ class PhpFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { return "all($domain), true).";\n"; } @@ -31,7 +31,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'php'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/PoFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/PoFileDumper.php index 0d822818c..313e50458 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/PoFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/PoFileDumper.php @@ -23,7 +23,7 @@ class PoFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $output = 'msgid ""'."\n"; $output .= 'msgstr ""'."\n"; @@ -114,7 +114,7 @@ private function getStandardRules(string $id) /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'po'; } @@ -124,7 +124,7 @@ private function escape(string $str): string return addcslashes($str, "\0..\37\42\134"); } - private function formatComments($comments, string $prefix = ''): ?string + private function formatComments(string|array $comments, string $prefix = ''): ?string { $output = null; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/QtFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/QtFileDumper.php index 406e9f006..819409fc0 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/QtFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/QtFileDumper.php @@ -23,7 +23,7 @@ class QtFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $dom = new \DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; @@ -54,7 +54,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'ts'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/XliffFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/XliffFileDumper.php index f7dbdcddf..b8a109a41 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/XliffFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/XliffFileDumper.php @@ -24,7 +24,7 @@ class XliffFileDumper extends FileDumper /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { $xliffVersion = '1.2'; if (\array_key_exists('xliff_version', $options)) { @@ -50,7 +50,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return 'xlf'; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Dumper/YamlFileDumper.php b/lam/lib/3rdParty/composer/symfony/translation/Dumper/YamlFileDumper.php index 0b21e8c83..d0cfbefaa 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Dumper/YamlFileDumper.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Dumper/YamlFileDumper.php @@ -23,7 +23,7 @@ */ class YamlFileDumper extends FileDumper { - private $extension; + private string $extension; public function __construct(string $extension = 'yml') { @@ -33,7 +33,7 @@ public function __construct(string $extension = 'yml') /** * {@inheritdoc} */ - public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) + public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string { if (!class_exists(Yaml::class)) { throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.'); @@ -55,7 +55,7 @@ public function formatCatalogue(MessageCatalogue $messages, string $domain, arra /** * {@inheritdoc} */ - protected function getExtension() + protected function getExtension(): string { return $this->extension; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Exception/ProviderException.php b/lam/lib/3rdParty/composer/symfony/translation/Exception/ProviderException.php index 571920da3..331ff7586 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Exception/ProviderException.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Exception/ProviderException.php @@ -19,7 +19,7 @@ class ProviderException extends RuntimeException implements ProviderExceptionInterface { private $response; - private $debug; + private string $debug; public function __construct(string $message, ResponseInterface $response, int $code = 0, \Exception $previous = null) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Extractor/AbstractFileExtractor.php b/lam/lib/3rdParty/composer/symfony/translation/Extractor/AbstractFileExtractor.php index 3bc878348..4c088b94f 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Extractor/AbstractFileExtractor.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Extractor/AbstractFileExtractor.php @@ -20,12 +20,7 @@ */ abstract class AbstractFileExtractor { - /** - * @param string|iterable $resource Files, a file or a directory - * - * @return iterable - */ - protected function extractFiles($resource) + protected function extractFiles(string|iterable $resource): iterable { if (is_iterable($resource)) { $files = []; @@ -49,11 +44,9 @@ private function toSplFileInfo(string $file): \SplFileInfo } /** - * @return bool - * * @throws InvalidArgumentException */ - protected function isFile(string $file) + protected function isFile(string $file): bool { if (!is_file($file)) { throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file)); @@ -68,9 +61,7 @@ protected function isFile(string $file) abstract protected function canBeExtracted(string $file); /** - * @param string|array $resource Files, a file or a directory - * * @return iterable */ - abstract protected function extractFromDirectory($resource); + abstract protected function extractFromDirectory(string|array $resource); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Extractor/ChainExtractor.php b/lam/lib/3rdParty/composer/symfony/translation/Extractor/ChainExtractor.php index 95dcf157c..e58e82f05 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Extractor/ChainExtractor.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Extractor/ChainExtractor.php @@ -25,7 +25,7 @@ class ChainExtractor implements ExtractorInterface * * @var ExtractorInterface[] */ - private $extractors = []; + private array $extractors = []; /** * Adds a loader to the translation extractor. @@ -48,7 +48,7 @@ public function setPrefix(string $prefix) /** * {@inheritdoc} */ - public function extract($directory, MessageCatalogue $catalogue) + public function extract(string|iterable $directory, MessageCatalogue $catalogue) { foreach ($this->extractors as $extractor) { $extractor->extract($directory, $catalogue); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Extractor/ExtractorInterface.php b/lam/lib/3rdParty/composer/symfony/translation/Extractor/ExtractorInterface.php index e1db8a9c8..b76a7f20b 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Extractor/ExtractorInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Extractor/ExtractorInterface.php @@ -26,7 +26,7 @@ interface ExtractorInterface * * @param string|iterable $resource Files, a file or a directory */ - public function extract($resource, MessageCatalogue $catalogue); + public function extract(string|iterable $resource, MessageCatalogue $catalogue); /** * Sets the prefix that should be used for new found messages. diff --git a/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpExtractor.php b/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpExtractor.php index 38c08d548..1b86cc591 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpExtractor.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpExtractor.php @@ -28,7 +28,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface /** * Prefix for new found message. */ - private $prefix = ''; + private string $prefix = ''; /** * The sequence that captures translation messages. @@ -131,7 +131,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface /** * {@inheritdoc} */ - public function extract($resource, MessageCatalogue $catalog) + public function extract(string|iterable $resource, MessageCatalogue $catalog) { $files = $this->extractFiles($resource); foreach ($files as $file) { @@ -151,12 +151,8 @@ public function setPrefix(string $prefix) /** * Normalizes a token. - * - * @param mixed $token - * - * @return string|null */ - protected function normalizeToken($token) + protected function normalizeToken(mixed $token): ?string { if (isset($token[1]) && 'b"' !== $token) { return $token[1]; @@ -311,11 +307,9 @@ protected function parseTokens(array $tokens, MessageCatalogue $catalog, string } /** - * @return bool - * * @throws \InvalidArgumentException */ - protected function canBeExtracted(string $file) + protected function canBeExtracted(string $file): bool { return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION); } @@ -323,7 +317,7 @@ protected function canBeExtracted(string $file) /** * {@inheritdoc} */ - protected function extractFromDirectory($directory) + protected function extractFromDirectory(string|array $directory): iterable { if (!class_exists(Finder::class)) { throw new \LogicException(sprintf('You cannot use "%s" as the "symfony/finder" package is not installed. Try running "composer require symfony/finder".', static::class)); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpStringTokenParser.php b/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpStringTokenParser.php index d114cc738..7fbd37c68 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpStringTokenParser.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Extractor/PhpStringTokenParser.php @@ -64,10 +64,8 @@ class PhpStringTokenParser * Parses a string token. * * @param string $str String token content - * - * @return string */ - public static function parse(string $str) + public static function parse(string $str): string { $bLength = 0; if ('b' === $str[0]) { @@ -90,10 +88,8 @@ public static function parse(string $str) * * @param string $str String without quotes * @param string|null $quote Quote type - * - * @return string */ - public static function parseEscapeSequences(string $str, string $quote = null) + public static function parseEscapeSequences(string $str, string $quote = null): string { if (null !== $quote) { $str = str_replace('\\'.$quote, $quote, $str); @@ -124,10 +120,8 @@ private static function parseCallback(array $matches): string * * @param string $startToken Doc string start token content (<<translator instanceof TranslatorInterface) { return $this->translator->trans($message, $parameters, null, $locale); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Formatter/MessageFormatterInterface.php b/lam/lib/3rdParty/composer/symfony/translation/Formatter/MessageFormatterInterface.php index b85dbfd11..d5c41c190 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Formatter/MessageFormatterInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Formatter/MessageFormatterInterface.php @@ -23,8 +23,6 @@ interface MessageFormatterInterface * @param string $message The message (may also be an object that can be cast to string) * @param string $locale The message locale * @param array $parameters An array of parameters for the message - * - * @return string */ - public function format(string $message, string $locale, array $parameters = []); + public function format(string $message, string $locale, array $parameters = []): string; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/LICENSE b/lam/lib/3rdParty/composer/symfony/translation/LICENSE index 0138f8f07..008370457 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/LICENSE +++ b/lam/lib/3rdParty/composer/symfony/translation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-present Fabien Potencier +Copyright (c) 2004-2023 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/lam/lib/3rdParty/composer/symfony/translation/Loader/ArrayLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/ArrayLoader.php index feed0de4b..35de9ef54 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/ArrayLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/ArrayLoader.php @@ -23,7 +23,7 @@ class ArrayLoader implements LoaderInterface /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { $resource = $this->flatten($resource); $catalogue = new MessageCatalogue($locale); @@ -46,11 +46,9 @@ private function flatten(array $messages): array foreach ($messages as $key => $value) { if (\is_array($value)) { foreach ($this->flatten($value) as $k => $v) { - if (null !== $v) { - $result[$key.'.'.$k] = $v; - } + $result[$key.'.'.$k] = $v; } - } elseif (null !== $value) { + } else { $result[$key] = $value; } } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/CsvFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/CsvFileLoader.php index 8d5d4db9a..76b00b151 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/CsvFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/CsvFileLoader.php @@ -20,14 +20,14 @@ */ class CsvFileLoader extends FileLoader { - private $delimiter = ';'; - private $enclosure = '"'; - private $escape = '\\'; + private string $delimiter = ';'; + private string $enclosure = '"'; + private string $escape = '\\'; /** * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { $messages = []; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/FileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/FileLoader.php index 4725ea6d6..e170d7617 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/FileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/FileLoader.php @@ -14,6 +14,7 @@ use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Translation\Exception\InvalidResourceException; use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Translation\MessageCatalogue; /** * @author Abdellatif Ait boudad @@ -23,7 +24,7 @@ abstract class FileLoader extends ArrayLoader /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { if (!stream_is_local($resource)) { throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource)); @@ -55,9 +56,7 @@ public function load($resource, string $locale, string $domain = 'messages') } /** - * @return array - * * @throws InvalidResourceException if stream content has an invalid format */ - abstract protected function loadResource(string $resource); + abstract protected function loadResource(string $resource): array; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuDatFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuDatFileLoader.php index 2a1aecc60..c3ca5fd08 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuDatFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuDatFileLoader.php @@ -26,7 +26,7 @@ class IcuDatFileLoader extends IcuResFileLoader /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { if (!stream_is_local($resource.'.dat')) { throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource)); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuResFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuResFileLoader.php index 6b7834e67..54c48f813 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuResFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/IcuResFileLoader.php @@ -26,7 +26,7 @@ class IcuResFileLoader implements LoaderInterface /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { if (!stream_is_local($resource)) { throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource)); @@ -71,11 +71,9 @@ public function load($resource, string $locale, string $domain = 'messages') * * @param \ResourceBundle $rb The ResourceBundle that will be flattened * @param array $messages Used internally for recursive calls - * @param string|null $path Current path being parsed, used internally for recursive calls - * - * @return array + * @param string $path Current path being parsed, used internally for recursive calls */ - protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null) + protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null): array { foreach ($rb as $key => $value) { $nodePath = $path ? $path.'.'.$key : $key; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/IniFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/IniFileLoader.php index 7398f7778..04e294d11 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/IniFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/IniFileLoader.php @@ -21,7 +21,7 @@ class IniFileLoader extends FileLoader /** * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { return parse_ini_file($resource, true); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/JsonFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/JsonFileLoader.php index 5aefba072..67a8d58ed 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/JsonFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/JsonFileLoader.php @@ -23,7 +23,7 @@ class JsonFileLoader extends FileLoader /** * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { $messages = []; if ($data = file_get_contents($resource)) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/LoaderInterface.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/LoaderInterface.php index 96b0c0d85..29d5560d1 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/LoaderInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/LoaderInterface.php @@ -25,14 +25,8 @@ interface LoaderInterface /** * Loads a locale. * - * @param mixed $resource A resource - * @param string $locale A locale - * @param string $domain The domain - * - * @return MessageCatalogue - * * @throws NotFoundResourceException when the resource cannot be found * @throws InvalidResourceException when the resource cannot be loaded */ - public function load($resource, string $locale, string $domain = 'messages'); + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/MoFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/MoFileLoader.php index 7fa2f2dcb..b0c891387 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/MoFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/MoFileLoader.php @@ -41,7 +41,7 @@ class MoFileLoader extends FileLoader * * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { $stream = fopen($resource, 'r'); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/PhpFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/PhpFileLoader.php index 40f64db27..ae299c2ac 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/PhpFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/PhpFileLoader.php @@ -18,12 +18,12 @@ */ class PhpFileLoader extends FileLoader { - private static $cache = []; + private static ?array $cache = []; /** * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(\ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { self::$cache = null; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/PoFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/PoFileLoader.php index ee143e203..6df161487 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/PoFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/PoFileLoader.php @@ -60,7 +60,7 @@ class PoFileLoader extends FileLoader * * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { $stream = fopen($resource, 'r'); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/QtFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/QtFileLoader.php index 9cf2fe976..6d5582d66 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/QtFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/QtFileLoader.php @@ -28,7 +28,7 @@ class QtFileLoader implements LoaderInterface /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { if (!class_exists(XmlUtils::class)) { throw new RuntimeException('Loading translations from the QT format requires the Symfony Config component.'); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/XliffFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/XliffFileLoader.php index 5c9794a54..670e19979 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/XliffFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/XliffFileLoader.php @@ -31,7 +31,7 @@ class XliffFileLoader implements LoaderInterface /** * {@inheritdoc} */ - public function load($resource, string $locale, string $domain = 'messages') + public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue { if (!class_exists(XmlUtils::class)) { throw new RuntimeException('Loading translations from the Xliff format requires the Symfony Config component.'); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Loader/YamlFileLoader.php b/lam/lib/3rdParty/composer/symfony/translation/Loader/YamlFileLoader.php index 8588e186a..5eccf99de 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Loader/YamlFileLoader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Loader/YamlFileLoader.php @@ -29,7 +29,7 @@ class YamlFileLoader extends FileLoader /** * {@inheritdoc} */ - protected function loadResource(string $resource) + protected function loadResource(string $resource): array { if (null === $this->yamlParser) { if (!class_exists(\Symfony\Component\Yaml\Parser::class)) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/LoggingTranslator.php b/lam/lib/3rdParty/composer/symfony/translation/LoggingTranslator.php index 6ccd48289..8c8441cdf 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/LoggingTranslator.php +++ b/lam/lib/3rdParty/composer/symfony/translation/LoggingTranslator.php @@ -40,7 +40,7 @@ public function __construct(TranslatorInterface $translator, LoggerInterface $lo /** * {@inheritdoc} */ - public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null) + public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string { $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale); $this->log($id, $domain, $locale); @@ -65,7 +65,7 @@ public function setLocale(string $locale) /** * {@inheritdoc} */ - public function getLocale() + public function getLocale(): string { return $this->translator->getLocale(); } @@ -73,7 +73,7 @@ public function getLocale() /** * {@inheritdoc} */ - public function getCatalogue(string $locale = null) + public function getCatalogue(string $locale = null): MessageCatalogueInterface { return $this->translator->getCatalogue($locale); } @@ -88,10 +88,8 @@ public function getCatalogues(): array /** * Gets the fallback locales. - * - * @return array */ - public function getFallbackLocales() + public function getFallbackLocales(): array { if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) { return $this->translator->getFallbackLocales(); diff --git a/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogue.php b/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogue.php index 9da3b7f00..848594b6b 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogue.php +++ b/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogue.php @@ -19,12 +19,12 @@ */ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface { - private $messages = []; - private $metadata = []; - private $resources = []; - private $locale; - private $fallbackCatalogue; - private $parent; + private array $messages = []; + private array $metadata = []; + private array $resources = []; + private string $locale; + private $fallbackCatalogue = null; + private ?self $parent = null; /** * @param array $messages An array of messages classified by domain @@ -38,7 +38,7 @@ public function __construct(string $locale, array $messages = []) /** * {@inheritdoc} */ - public function getLocale() + public function getLocale(): string { return $this->locale; } @@ -46,7 +46,7 @@ public function getLocale() /** * {@inheritdoc} */ - public function getDomains() + public function getDomains(): array { $domains = []; @@ -63,7 +63,7 @@ public function getDomains() /** * {@inheritdoc} */ - public function all(string $domain = null) + public function all(string $domain = null): array { if (null !== $domain) { // skip messages merge if intl-icu requested explicitly @@ -99,7 +99,7 @@ public function set(string $id, string $translation, string $domain = 'messages' /** * {@inheritdoc} */ - public function has(string $id, string $domain = 'messages') + public function has(string $id, string $domain = 'messages'): bool { if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) { return true; @@ -115,7 +115,7 @@ public function has(string $id, string $domain = 'messages') /** * {@inheritdoc} */ - public function defines(string $id, string $domain = 'messages') + public function defines(string $id, string $domain = 'messages'): bool { return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]); } @@ -123,7 +123,7 @@ public function defines(string $id, string $domain = 'messages') /** * {@inheritdoc} */ - public function get(string $id, string $domain = 'messages') + public function get(string $id, string $domain = 'messages'): string { if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) { return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]; @@ -228,7 +228,7 @@ public function addFallbackCatalogue(MessageCatalogueInterface $catalogue) /** * {@inheritdoc} */ - public function getFallbackCatalogue() + public function getFallbackCatalogue(): ?MessageCatalogueInterface { return $this->fallbackCatalogue; } @@ -236,7 +236,7 @@ public function getFallbackCatalogue() /** * {@inheritdoc} */ - public function getResources() + public function getResources(): array { return array_values($this->resources); } @@ -252,7 +252,7 @@ public function addResource(ResourceInterface $resource) /** * {@inheritdoc} */ - public function getMetadata(string $key = '', string $domain = 'messages') + public function getMetadata(string $key = '', string $domain = 'messages'): mixed { if ('' == $domain) { return $this->metadata; @@ -274,7 +274,7 @@ public function getMetadata(string $key = '', string $domain = 'messages') /** * {@inheritdoc} */ - public function setMetadata(string $key, $value, string $domain = 'messages') + public function setMetadata(string $key, mixed $value, string $domain = 'messages') { $this->metadata[$domain][$key] = $value; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogueInterface.php b/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogueInterface.php index 965bf008f..75e3a2fa7 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogueInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/MessageCatalogueInterface.php @@ -24,28 +24,22 @@ interface MessageCatalogueInterface /** * Gets the catalogue locale. - * - * @return string */ - public function getLocale(); + public function getLocale(): string; /** * Gets the domains. - * - * @return array */ - public function getDomains(); + public function getDomains(): array; /** * Gets the messages within a given domain. * * If $domain is null, it returns all messages. * - * @param string|null $domain The domain name - * - * @return array + * @param string $domain The domain name */ - public function all(string $domain = null); + public function all(string $domain = null): array; /** * Sets a message translation. @@ -61,30 +55,24 @@ public function set(string $id, string $translation, string $domain = 'messages' * * @param string $id The message id * @param string $domain The domain name - * - * @return bool */ - public function has(string $id, string $domain = 'messages'); + public function has(string $id, string $domain = 'messages'): bool; /** * Checks if a message has a translation (it does not take into account the fallback mechanism). * * @param string $id The message id * @param string $domain The domain name - * - * @return bool */ - public function defines(string $id, string $domain = 'messages'); + public function defines(string $id, string $domain = 'messages'): bool; /** * Gets a message translation. * * @param string $id The message id * @param string $domain The domain name - * - * @return string */ - public function get(string $id, string $domain = 'messages'); + public function get(string $id, string $domain = 'messages'): string; /** * Sets translations for a given domain. @@ -119,17 +107,15 @@ public function addFallbackCatalogue(self $catalogue); /** * Gets the fallback catalogue. - * - * @return self|null */ - public function getFallbackCatalogue(); + public function getFallbackCatalogue(): ?self; /** * Returns an array of resources loaded to build this collection. * * @return ResourceInterface[] */ - public function getResources(); + public function getResources(): array; /** * Adds a resource for this collection. diff --git a/lam/lib/3rdParty/composer/symfony/translation/MetadataAwareInterface.php b/lam/lib/3rdParty/composer/symfony/translation/MetadataAwareInterface.php index 2216eed94..2eaaceb36 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/MetadataAwareInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/MetadataAwareInterface.php @@ -27,14 +27,12 @@ interface MetadataAwareInterface * * @return mixed The value that was set or an array with the domains/keys or null */ - public function getMetadata(string $key = '', string $domain = 'messages'); + public function getMetadata(string $key = '', string $domain = 'messages'): mixed; /** * Adds metadata to a message domain. - * - * @param mixed $value */ - public function setMetadata(string $key, $value, string $domain = 'messages'); + public function setMetadata(string $key, mixed $value, string $domain = 'messages'); /** * Deletes metadata for the given key and domain. diff --git a/lam/lib/3rdParty/composer/symfony/translation/Provider/Dsn.php b/lam/lib/3rdParty/composer/symfony/translation/Provider/Dsn.php index 820cabfb3..0f74d17fb 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Provider/Dsn.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Provider/Dsn.php @@ -20,14 +20,14 @@ */ final class Dsn { - private $scheme; - private $host; - private $user; - private $password; - private $port; - private $path; - private $options; - private $originalDsn; + private ?string $scheme; + private ?string $host; + private ?string $user; + private ?string $password; + private ?int $port; + private ?string $path; + private array $options = []; + private string $originalDsn; public function __construct(string $dsn) { @@ -79,7 +79,7 @@ public function getPort(int $default = null): ?int return $this->port ?? $default; } - public function getOption(string $key, $default = null) + public function getOption(string $key, mixed $default = null) { return $this->options[$key] ?? $default; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Provider/FilteringProvider.php b/lam/lib/3rdParty/composer/symfony/translation/Provider/FilteringProvider.php index 5f970a2e5..a43fedc71 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Provider/FilteringProvider.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Provider/FilteringProvider.php @@ -22,8 +22,8 @@ class FilteringProvider implements ProviderInterface { private $provider; - private $locales; - private $domains; + private array $locales; + private array $domains; public function __construct(ProviderInterface $provider, array $locales, array $domains = []) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Provider/TranslationProviderCollectionFactory.php b/lam/lib/3rdParty/composer/symfony/translation/Provider/TranslationProviderCollectionFactory.php index 81db3a5f1..6300c8750 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Provider/TranslationProviderCollectionFactory.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Provider/TranslationProviderCollectionFactory.php @@ -18,8 +18,8 @@ */ class TranslationProviderCollectionFactory { - private $factories; - private $enabledLocales; + private iterable $factories; + private array $enabledLocales; /** * @param iterable $factories diff --git a/lam/lib/3rdParty/composer/symfony/translation/PseudoLocalizationTranslator.php b/lam/lib/3rdParty/composer/symfony/translation/PseudoLocalizationTranslator.php index c769bdad0..ba7319d4f 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/PseudoLocalizationTranslator.php +++ b/lam/lib/3rdParty/composer/symfony/translation/PseudoLocalizationTranslator.php @@ -21,15 +21,15 @@ final class PseudoLocalizationTranslator implements TranslatorInterface private const EXPANSION_CHARACTER = '~'; private $translator; - private $accents; - private $expansionFactor; - private $brackets; - private $parseHTML; + private bool $accents; + private float $expansionFactor; + private bool $brackets; + private bool $parseHTML; /** * @var string[] */ - private $localizableHTMLAttributes; + private array $localizableHTMLAttributes; /** * Available options: diff --git a/lam/lib/3rdParty/composer/symfony/translation/Reader/TranslationReader.php b/lam/lib/3rdParty/composer/symfony/translation/Reader/TranslationReader.php index e8e8638a0..bbc687e13 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Reader/TranslationReader.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Reader/TranslationReader.php @@ -27,7 +27,7 @@ class TranslationReader implements TranslationReaderInterface * * @var array */ - private $loaders = []; + private array $loaders = []; /** * Adds a loader to the translation extractor. diff --git a/lam/lib/3rdParty/composer/symfony/translation/Resources/bin/translation-status.php b/lam/lib/3rdParty/composer/symfony/translation/Resources/bin/translation-status.php index 53e642c00..4fe814cf6 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Resources/bin/translation-status.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Resources/bin/translation-status.php @@ -66,7 +66,7 @@ continue; } - if (0 === strpos($argumentOrOption, '-')) { + if (str_starts_with($argumentOrOption, '-')) { $config['verbose_output'] = true; } else { $config['locale_to_analyze'] = $argumentOrOption; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderFactoryTestCase.php b/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderFactoryTestCase.php index 5df82ebe2..d6510e0dd 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderFactoryTestCase.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderFactoryTestCase.php @@ -33,7 +33,7 @@ abstract class ProviderFactoryTestCase extends TestCase { protected $client; protected $logger; - protected $defaultLocale; + protected string $defaultLocale; protected $loader; protected $xliffFileDumper; @@ -42,17 +42,17 @@ abstract public function createFactory(): ProviderFactoryInterface; /** * @return iterable */ - abstract public static function supportsProvider(): iterable; + abstract public function supportsProvider(): iterable; /** - * @return iterable + * @return iterable */ - abstract public static function createProvider(): iterable; + abstract public function createProvider(): iterable; /** * @return iterable */ - public static function unsupportedSchemeProvider(): iterable + public function unsupportedSchemeProvider(): iterable { return []; } @@ -60,7 +60,7 @@ public static function unsupportedSchemeProvider(): iterable /** * @return iterable */ - public static function incompleteDsnProvider(): iterable + public function incompleteDsnProvider(): iterable { return []; } @@ -122,26 +122,26 @@ public function testIncompleteDsnException(string $dsn, string $message = null) protected function getClient(): HttpClientInterface { - return $this->client ?? $this->client = new MockHttpClient(); + return $this->client ??= new MockHttpClient(); } protected function getLogger(): LoggerInterface { - return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class); + return $this->logger ??= $this->createMock(LoggerInterface::class); } protected function getDefaultLocale(): string { - return $this->defaultLocale ?? $this->defaultLocale = 'en'; + return $this->defaultLocale ??= 'en'; } protected function getLoader(): LoaderInterface { - return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class); + return $this->loader ??= $this->createMock(LoaderInterface::class); } protected function getXliffFileDumper(): XliffFileDumper { - return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class); + return $this->xliffFileDumper ??= $this->createMock(XliffFileDumper::class); } } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderTestCase.php b/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderTestCase.php index cb8a03fc3..5ae26829b 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderTestCase.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Test/ProviderTestCase.php @@ -30,16 +30,16 @@ abstract class ProviderTestCase extends TestCase { protected $client; protected $logger; - protected $defaultLocale; + protected string $defaultLocale; protected $loader; protected $xliffFileDumper; - abstract public static function createProvider(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, string $defaultLocale, string $endpoint): ProviderInterface; + abstract public function createProvider(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, string $defaultLocale, string $endpoint): ProviderInterface; /** - * @return iterable + * @return iterable */ - abstract public static function toStringProvider(): iterable; + abstract public function toStringProvider(): iterable; /** * @dataProvider toStringProvider @@ -51,26 +51,26 @@ public function testToString(ProviderInterface $provider, string $expected) protected function getClient(): MockHttpClient { - return $this->client ?? $this->client = new MockHttpClient(); + return $this->client ??= new MockHttpClient(); } protected function getLoader(): LoaderInterface { - return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class); + return $this->loader ??= $this->createMock(LoaderInterface::class); } protected function getLogger(): LoggerInterface { - return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class); + return $this->logger ??= $this->createMock(LoggerInterface::class); } protected function getDefaultLocale(): string { - return $this->defaultLocale ?? $this->defaultLocale = 'en'; + return $this->defaultLocale ??= 'en'; } protected function getXliffFileDumper(): XliffFileDumper { - return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class); + return $this->xliffFileDumper ??= $this->createMock(XliffFileDumper::class); } } diff --git a/lam/lib/3rdParty/composer/symfony/translation/TranslatableMessage.php b/lam/lib/3rdParty/composer/symfony/translation/TranslatableMessage.php index 282d289c0..b1a3b6b13 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/TranslatableMessage.php +++ b/lam/lib/3rdParty/composer/symfony/translation/TranslatableMessage.php @@ -19,9 +19,9 @@ */ class TranslatableMessage implements TranslatableInterface { - private $message; - private $parameters; - private $domain; + private string $message; + private array $parameters; + private ?string $domain; public function __construct(string $message, array $parameters = [], string $domain = null) { diff --git a/lam/lib/3rdParty/composer/symfony/translation/Translator.php b/lam/lib/3rdParty/composer/symfony/translation/Translator.php index dc0626093..05e84d0cc 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Translator.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Translator.php @@ -37,54 +37,33 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA */ protected $catalogues = []; - /** - * @var string - */ - private $locale; + private string $locale; /** * @var string[] */ - private $fallbackLocales = []; + private array $fallbackLocales = []; /** * @var LoaderInterface[] */ - private $loaders = []; + private array $loaders = []; - /** - * @var array - */ - private $resources = []; + private array $resources = []; - /** - * @var MessageFormatterInterface - */ private $formatter; - /** - * @var string - */ - private $cacheDir; + private ?string $cacheDir; - /** - * @var bool - */ - private $debug; + private bool $debug; - private $cacheVary; + private array $cacheVary; - /** - * @var ConfigCacheFactoryInterface|null - */ private $configCacheFactory; - /** - * @var array|null - */ - private $parentLocales; + private array $parentLocales; - private $hasIntlFormatter; + private bool $hasIntlFormatter; /** * @throws InvalidArgumentException If a locale contains invalid characters @@ -127,7 +106,7 @@ public function addLoader(string $format, LoaderInterface $loader) * * @throws InvalidArgumentException If the locale contains invalid characters */ - public function addResource(string $format, $resource, string $locale, string $domain = null) + public function addResource(string $format, mixed $resource, string $locale, string $domain = null) { if (null === $domain) { $domain = 'messages'; @@ -157,7 +136,7 @@ public function setLocale(string $locale) /** * {@inheritdoc} */ - public function getLocale() + public function getLocale(): string { return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en'); } @@ -194,7 +173,7 @@ public function getFallbackLocales(): array /** * {@inheritdoc} */ - public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null) + public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string { if (null === $id || '' === $id) { return ''; @@ -229,7 +208,7 @@ public function trans(?string $id, array $parameters = [], string $domain = null /** * {@inheritdoc} */ - public function getCatalogue(string $locale = null) + public function getCatalogue(string $locale = null): MessageCatalogueInterface { if (!$locale) { $locale = $this->getLocale(); @@ -257,7 +236,7 @@ public function getCatalogues(): array * * @return LoaderInterface[] */ - protected function getLoaders() + protected function getLoaders(): array { return $this->loaders; } @@ -409,9 +388,7 @@ private function loadFallbackCatalogues(string $locale): void protected function computeFallbackLocales(string $locale) { - if (null === $this->parentLocales) { - $this->parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true); - } + $this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true); $originLocale = $locale; $locales = []; @@ -468,9 +445,7 @@ protected function assertValidLocale(string $locale) */ private function getConfigCacheFactory(): ConfigCacheFactoryInterface { - if (!$this->configCacheFactory) { - $this->configCacheFactory = new ConfigCacheFactory($this->debug); - } + $this->configCacheFactory ??= new ConfigCacheFactory($this->debug); return $this->configCacheFactory; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/TranslatorBag.php b/lam/lib/3rdParty/composer/symfony/translation/TranslatorBag.php index 6a4df3c3c..9be3458c1 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/TranslatorBag.php +++ b/lam/lib/3rdParty/composer/symfony/translation/TranslatorBag.php @@ -17,7 +17,7 @@ final class TranslatorBag implements TranslatorBagInterface { /** @var MessageCatalogue[] */ - private $catalogues = []; + private array $catalogues = []; public function addCatalogue(MessageCatalogue $catalogue): void { @@ -70,7 +70,7 @@ public function diff(TranslatorBagInterface $diffBag): self $operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::NEW_BATCH); $newCatalogue = new MessageCatalogue($locale); - foreach ($catalogue->getDomains() as $domain) { + foreach ($operation->getDomains() as $domain) { $newCatalogue->add($operation->getNewMessages($domain), $domain); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/TranslatorBagInterface.php b/lam/lib/3rdParty/composer/symfony/translation/TranslatorBagInterface.php index 422897735..a787acf12 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/TranslatorBagInterface.php +++ b/lam/lib/3rdParty/composer/symfony/translation/TranslatorBagInterface.php @@ -14,10 +14,6 @@ use Symfony\Component\Translation\Exception\InvalidArgumentException; /** - * TranslatorBagInterface. - * - * @method MessageCatalogueInterface[] getCatalogues() Returns all catalogues of the instance - * * @author Abdellatif Ait boudad */ interface TranslatorBagInterface @@ -27,9 +23,14 @@ interface TranslatorBagInterface * * @param string|null $locale The locale or null to use the default * - * @return MessageCatalogueInterface - * * @throws InvalidArgumentException If the locale contains invalid characters */ - public function getCatalogue(string $locale = null); + public function getCatalogue(string $locale = null): MessageCatalogueInterface; + + /** + * Returns all catalogues of the instance. + * + * @return MessageCatalogueInterface[] + */ + public function getCatalogues(): array; } diff --git a/lam/lib/3rdParty/composer/symfony/translation/Util/ArrayConverter.php b/lam/lib/3rdParty/composer/symfony/translation/Util/ArrayConverter.php index f69c2e3c6..60b8be6e0 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Util/ArrayConverter.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Util/ArrayConverter.php @@ -30,10 +30,8 @@ class ArrayConverter * For example this array('foo.bar' => 'value') will be converted to ['foo' => ['bar' => 'value']]. * * @param array $messages Linear messages array - * - * @return array */ - public static function expandToTree(array $messages) + public static function expandToTree(array $messages): array { $tree = []; diff --git a/lam/lib/3rdParty/composer/symfony/translation/Util/XliffUtils.php b/lam/lib/3rdParty/composer/symfony/translation/Util/XliffUtils.php index e4373a7d5..85ecc8504 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Util/XliffUtils.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Util/XliffUtils.php @@ -85,11 +85,6 @@ public static function validateSchema(\DOMDocument $dom): array private static function shouldEnableEntityLoader(): bool { - // Version prior to 8.0 can be enabled without deprecation - if (\PHP_VERSION_ID < 80000) { - return true; - } - static $dom, $schema; if (null === $dom) { $dom = new \DOMDocument(); diff --git a/lam/lib/3rdParty/composer/symfony/translation/Writer/TranslationWriter.php b/lam/lib/3rdParty/composer/symfony/translation/Writer/TranslationWriter.php index 96d608f07..5dd3a5c40 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/Writer/TranslationWriter.php +++ b/lam/lib/3rdParty/composer/symfony/translation/Writer/TranslationWriter.php @@ -26,7 +26,7 @@ class TranslationWriter implements TranslationWriterInterface /** * @var array */ - private $dumpers = []; + private array $dumpers = []; /** * Adds a dumper to the writer. @@ -38,10 +38,8 @@ public function addDumper(string $format, DumperInterface $dumper) /** * Obtains the list of supported formats. - * - * @return array */ - public function getFormats() + public function getFormats(): array { return array_keys($this->dumpers); } diff --git a/lam/lib/3rdParty/composer/symfony/translation/composer.json b/lam/lib/3rdParty/composer/symfony/translation/composer.json index 5c9266b7e..abe8b972c 100644 --- a/lam/lib/3rdParty/composer/symfony/translation/composer.json +++ b/lam/lib/3rdParty/composer/symfony/translation/composer.json @@ -16,35 +16,33 @@ } ], "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.0.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^2.3" + "symfony/translation-contracts": "^2.3|^3.0" }, "require-dev": { - "symfony/config": "^4.4|^5.0|^6.0", + "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.0|^6.0", - "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", "symfony/polyfill-intl-icu": "^1.21", "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^4.4|^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/yaml": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", "psr/log": "^1|^2|^3" }, "conflict": { - "symfony/config": "<4.4", - "symfony/dependency-injection": "<5.0", - "symfony/http-kernel": "<5.0", - "symfony/twig-bundle": "<5.0", - "symfony/yaml": "<4.4", - "symfony/console": "<5.3" + "symfony/config": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4", + "symfony/console": "<5.4" }, "provide": { - "symfony/translation-implementation": "2.3" + "symfony/translation-implementation": "2.3|3.0" }, "suggest": { "symfony/config": "", diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/.whitesource b/lam/lib/3rdParty/composer/voku/portable-ascii/.whitesource deleted file mode 100644 index 55b922e8c..000000000 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/.whitesource +++ /dev/null @@ -1,12 +0,0 @@ -{ - "scanSettings": { - "baseBranches": [] - }, - "checkRunSettings": { - "vulnerableCheckRunConclusionLevel": "failure", - "displayMode": "diff" - }, - "issueSettings": { - "minSeverityLevel": "LOW" - } -} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/CHANGELOG.md b/lam/lib/3rdParty/composer/voku/portable-ascii/CHANGELOG.md index 04b64acdd..12fc393a7 100644 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/voku/portable-ascii/CHANGELOG.md @@ -1,12 +1,23 @@ # Changelog -### 1.6.1 (2021-01-24) +### 2.0.1 (2022-03-08) + +- "To people of Russia": There is a war in Ukraine right now. The forces of the Russian Federation are attacking civilians. +- optimize some phpdocs + +### 2.0.0 (2022-01-24) + +- prefer "Russian - Passport (2013), ICAO" instead of "Russian - GOST 7.79-2000(B)" +- fix "Ukrainian" char-mapping (thanks to @Andr1yk0) +- fix "Persian" char-mapping (thanks to @frost-cyber) + +### 1.6.1 (2022-01-24) - revert: prefer "Russian - Passport (2013), ICAO" instead of "Russian - GOST 7.79-2000(B)" - revert: fix "Ukrainian" char-mapping (thanks to @Andr1yk0) - revert: fix "Persian" char-mapping (thanks to @frost-cyber) -### 1.6.0 (2021-01-24) +### 1.6.0 (2022-01-24) - prefer "Russian - Passport (2013), ICAO" instead of "Russian - GOST 7.79-2000(B)" - fix "Ukrainian" char-mapping (thanks to @Andr1yk0) diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/README.md b/lam/lib/3rdParty/composer/voku/portable-ascii/README.md index 929c21e29..3ce36d604 100644 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/README.md +++ b/lam/lib/3rdParty/composer/voku/portable-ascii/README.md @@ -1,4 +1,6 @@ [//]: # (AUTO-GENERATED BY "PHP README Helper": base file -> docs/base.md) +[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) + [![Build Status](https://github.com/voku/portable-ascii/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/voku/portable-ascii/actions) [![Build status](https://ci.appveyor.com/api/projects/status/gnejjnk7qplr7f5t/branch/master?svg=true)](https://ci.appveyor.com/project/voku/portable-ascii/branch/master) [![codecov.io](https://codecov.io/github/voku/portable-ascii/coverage.svg?branch=master)](https://codecov.io/github/voku/portable-ascii?branch=master) @@ -99,8 +101,9 @@ The API from the "ASCII"-Class is written as small static methods. normalize_whitespace remove_invisible_characters to_ascii -to_filename -to_slugify +to_ascii_remap +to_filename +to_slugify to_transliterate @@ -152,7 +155,7 @@ echo $array['orig'][$tmpKey]; // 'ё' **Parameters:** -- `string $language [optional]

Language of the source string e.g.: en, de_at, or de-ch. +- `ASCII::* $language [optional]

Language of the source string e.g.: en, de_at, or de-ch. (default is 'en') | ASCII::*_LANGUAGE_CODE

` - `bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " pound ".

` - `bool $asOrigReplaceArray [optional]

TRUE === return {orig: string[], replace: string[]} @@ -308,7 +311,7 @@ ASCII::to_ascii('�Düsseldorf�', 'en'); // Dusseldorf **Parameters:** - `string $str

The input string.

` -- `string $language [optional]

Language of the source string. +- `ASCII::* $language [optional]

Language of the source string. (default is 'en') | ASCII::*_LANGUAGE_CODE

` - `bool $remove_unsupported_chars [optional]

Whether or not to remove the unsupported characters.

` @@ -325,6 +328,26 @@ language

` -------- +#### to_ascii_remap(string $str1, string $str2): string[] + +WARNING: This method will return broken characters and is only for special cases. + +Convert two UTF-8 encoded string to a single-byte strings suitable for +functions that need the same string length after the conversion. + +The function simply uses (and updates) a tailored dynamic encoding +(in/out map parameter) where non-ascii characters are remapped to +the range [128-255] in order of appearance. + +**Parameters:** +- `string $str1` +- `string $str2` + +**Return:** +- `string[]` + +-------- + #### to_filename(string $str, bool $use_transliterate, string $fallback_char): string Convert given string to safe filename (and keep string case). @@ -356,7 +379,7 @@ also be supplied for language-specific transliteration. **Parameters:** - `string $str` - `string $separator [optional]

The string used to replace whitespace.

` -- `string $language [optional]

Language of the source string. +- `ASCII::* $language [optional]

Language of the source string. (default is 'en') | ASCII::*_LANGUAGE_CODE

` - `array $replacements [optional]

A map of replaceable strings.

` - `bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/build/composer.json b/lam/lib/3rdParty/composer/voku/portable-ascii/build/composer.json deleted file mode 100644 index 30f30c3cc..000000000 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/build/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require-dev": { - "voku/php-readme-helper": "~0.6" - } -} diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/build/docs/base.md b/lam/lib/3rdParty/composer/voku/portable-ascii/build/docs/base.md deleted file mode 100644 index ca949d8b6..000000000 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/build/docs/base.md +++ /dev/null @@ -1,127 +0,0 @@ -[![Build Status](https://github.com/voku/portable-ascii/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/voku/portable-ascii/actions) -[![Build status](https://ci.appveyor.com/api/projects/status/gnejjnk7qplr7f5t/branch/master?svg=true)](https://ci.appveyor.com/project/voku/portable-ascii/branch/master) -[![codecov.io](https://codecov.io/github/voku/portable-ascii/coverage.svg?branch=master)](https://codecov.io/github/voku/portable-ascii?branch=master) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/997c9bb10d1c4791967bdf2e42013e8e)](https://www.codacy.com/app/voku/portable-ascii) -[![Latest Stable Version](https://poser.pugx.org/voku/portable-ascii/v/stable)](https://packagist.org/packages/voku/portable-ascii) -[![Total Downloads](https://poser.pugx.org/voku/portable-ascii/downloads)](https://packagist.org/packages/voku/portable-ascii) -[![License](https://poser.pugx.org/voku/portable-ascii/license)](https://packagist.org/packages/voku/portable-ascii) -[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/moelleken) -[![Donate to this project using Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://www.patreon.com/voku) - -# 🔡 Portable ASCII - -## Description - -It is written in PHP (PHP 7+) and can work without "mbstring", "iconv" or any other extra encoding php-extension on your server. - -The benefit of Portable ASCII is that it is easy to use, easy to bundle. - -The project based on ... -+ Sean M. Burke's work (https://metacpan.org/pod/Text::Unidecode) -+ Tomaz Solc's work (https://pypi.org/project/Unidecode/) -+ Portable UTF-8 work (https://github.com/voku/portable-utf8) -+ Daniel St. Jules's work (https://github.com/danielstjules/Stringy) -+ Johnny Broadway's work (https://github.com/jbroadway/urlify) -+ and many cherry-picks from "github"-gists and "Stack Overflow"-snippets ... - -## Index - -* [Alternative](#alternative) -* [Install](#install-portable-ascii-via-composer-require) -* [Why Portable ASCII?](#why-portable-ascii) -* [Requirements and Recommendations](#requirements-and-recommendations) -* [Usage](#usage) -* [Class methods](#class-methods) -* [Unit Test](#unit-test) -* [License and Copyright](#license-and-copyright) - -## Alternative - -If you like a more Object Oriented Way to edit strings, then you can take a look at [voku/Stringy](https://github.com/voku/Stringy), it's a fork of "danielstjules/Stringy" but it used the "Portable ASCII"-Class and some extra methods. - -```php -// Portable ASCII -use voku\helper\ASCII; -ASCII::to_transliterate('déjà σσς iıii'); // 'deja sss iiii' - -// voku/Stringy -use Stringy\Stringy as S; -$stringy = S::create('déjà σσς iıii'); -$stringy->toTransliterate(); // 'deja sss iiii' -``` - -## Install "Portable ASCII" via "composer require" -```shell -composer require voku/portable-ascii -``` - -## Why Portable ASCII?[]() -I need ASCII char handling in different classes and before I added this functions into "Portable UTF-8", -but this repo is more modular and portable, because it has no dependencies. - -## Requirements and Recommendations - -* No extensions are required to run this library. Portable ASCII only needs PCRE library that is available by default since PHP 4.2.0 and cannot be disabled since PHP 5.3.0. "\u" modifier support in PCRE for ASCII handling is not a must. -* PHP 7.0 is the minimum requirement -* PHP 8.0 is also supported - -## Usage - -Example: ASCII::to_ascii() -```php - echo ASCII::to_ascii('�Düsseldorf�', 'de'); - - // will output - // Duesseldorf - - echo ASCII::to_ascii('�Düsseldorf�', 'en'); - - // will output - // Dusseldorf -``` - -# Portable ASCII | API - -The API from the "ASCII"-Class is written as small static methods. - - -## Class methods - -%__functions_index__voku\helper\ASCII__% - -%__functions_list__voku\helper\ASCII__% - - -## Unit Test - -1) [Composer](https://getcomposer.org) is a prerequisite for running the tests. - -``` -composer install -``` - -2) The tests can be executed by running this command from the root directory: - -```bash -./vendor/bin/phpunit -``` - -### Support - -For support and donations please visit [Github](https://github.com/voku/portable-ascii/) | [Issues](https://github.com/voku/portable-ascii/issues) | [PayPal](https://paypal.me/moelleken) | [Patreon](https://www.patreon.com/voku). - -For status updates and release announcements please visit [Releases](https://github.com/voku/portable-ascii/releases) | [Twitter](https://twitter.com/suckup_de) | [Patreon](https://www.patreon.com/voku/posts). - -For professional support please contact [me](https://about.me/voku). - -### Thanks - -- Thanks to [GitHub](https://github.com) (Microsoft) for hosting the code and a good infrastructure including Issues-Managment, etc. -- Thanks to [IntelliJ](https://www.jetbrains.com) as they make the best IDEs for PHP and they gave me an open source license for PhpStorm! -- Thanks to [Travis CI](https://travis-ci.com/) for being the most awesome, easiest continous integration tool out there! -- Thanks to [StyleCI](https://styleci.io/) for the simple but powerful code style check. -- Thanks to [PHPStan](https://github.com/phpstan/phpstan) && [Psalm](https://github.com/vimeo/psalm) for really great Static analysis tools and for discover bugs in the code! - -### License and Copyright - -Released under the MIT License - see `LICENSE.txt` for details. diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_docs.php b/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_docs.php deleted file mode 100644 index c86f1f195..000000000 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_docs.php +++ /dev/null @@ -1,26 +0,0 @@ -templateMethod = <<↑ -%description% - -**Parameters:** -%params% - -**Return:** -%return% - --------- - -RAW; -$readmeText = ($readmeGenerator)->generate( - __DIR__ . '/../src/voku/helper/ASCII.php', - __DIR__ . '/docs/base.md' -); - -file_put_contents(__DIR__ . '/../README.md', $readmeText); diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_max_key_length.php b/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_max_key_length.php deleted file mode 100644 index 743d389f5..000000000 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/build/generate_max_key_length.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ + /** @var array>> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols; @@ -329,6 +343,7 @@ public static function charsArrayWithMultiLanguageValues(bool $replace_extra_sym * @return array *

An array of replacements.

* + * @phpstan-param ASCII::*_LANGUAGE_CODE $language * @phpstan-return array{orig: string[], replace: string[]}|array */ public static function charsArrayWithOneLanguage( @@ -339,9 +354,7 @@ public static function charsArrayWithOneLanguage( $language = self::get_language($language); // init - /** - * @var array - */ + /** @var array|array{orig: string[], replace: string[]}>> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols . '-' . $asOrigReplaceArray; @@ -432,9 +445,7 @@ public static function charsArrayWithSingleLanguageValues( bool $asOrigReplaceArray = true ): array { // init - /** - * @var array - */ + /** @var array|array{orig: string[], replace: string[]}> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols . '-' . $asOrigReplaceArray; @@ -460,6 +471,7 @@ public static function charsArrayWithSingleLanguageValues( } } + /** @phpstan-ignore-next-line - ... error? */ $CHARS_ARRAY[$cacheKey] = \array_merge([], ...$CHARS_ARRAY[$cacheKey]); if ($asOrigReplaceArray) { @@ -578,19 +590,13 @@ public static function normalize_msword(string $str): string return ''; } - /** - * @var array{orig: string[], replace: string[]} - */ + /** @var array{orig: string[], replace: string[]} */ static $MSWORD_CACHE = ['orig' => [], 'replace' => []]; if (empty($MSWORD_CACHE['orig'])) { self::prepareAsciiMaps(); - /** - * @psalm-suppress PossiblyNullArrayAccess - we use the prepare* methods here, so we don't get NULL here - * - * @var array - */ + /** @var array */ $map = self::$ASCII_MAPS[self::EXTRA_MSWORD_CHARS_LANGUAGE_CODE] ?? []; $MSWORD_CACHE = [ @@ -630,9 +636,7 @@ public static function normalize_whitespace( return ''; } - /** - * @var array> - */ + /** @var array> */ static $WHITESPACE_CACHE = []; $cacheKey = (int) $keepNonBreakingSpace; @@ -665,13 +669,11 @@ public static function normalize_whitespace( unset($WHITESPACE_CACHE[$cacheKey]["\xc2\xa0"]); } - $WHITESPACE_CACHE[$cacheKey] = \array_keys($WHITESPACE_CACHE[$cacheKey]); + $WHITESPACE_CACHE[$cacheKey] = array_keys($WHITESPACE_CACHE[$cacheKey]); } if (!$keepBidiUnicodeControls) { - /** - * @var array|null - */ + /** @var array|null */ static $BIDI_UNICODE_CONTROLS_CACHE = null; if ($BIDI_UNICODE_CONTROLS_CACHE === null) { @@ -758,45 +760,6 @@ public static function to_ascii_remap(string $str1, string $str2): array return [$str1, $str2]; } - /** - * WARNING: This method will return broken characters and is only for special cases. - * - * Convert a UTF-8 encoded string to a single-byte string suitable for - * functions that need the same string length after the conversion. - * - * The function simply uses (and updates) a tailored dynamic encoding - * (in/out map parameter) where non-ascii characters are remapped to - * the range [128-255] in order of appearance. - * - * Thus, it supports up to 128 different multibyte code points max over - * the whole set of strings sharing this encoding. - * - * Source: https://github.com/KEINOS/mb_levenshtein - * - * @param string $str UTF-8 string to be converted to extended ASCII. - * @return string Mapped borken string. - */ - private static function to_ascii_remap_intern(string $str, array &$map): string - { - // find all utf-8 characters - $matches = []; - if (!\preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $str, $matches)) { - return $str; // plain ascii string - } - - // update the encoding map with the characters not already met - $mapCount = \count($map); - foreach ($matches[0] as $mbc) { - if (!isset($map[$mbc])) { - $map[$mbc] = \chr(128 + $mapCount); - $mapCount++; - } - } - - // finally remap non-ascii characters - return \strtr($str, $map); - } - /** * Returns an ASCII version of the string. A set of non-ASCII characters are * replaced with their closest ASCII counterparts, and the rest are removed @@ -826,6 +789,8 @@ private static function to_ascii_remap_intern(string $str, array &$map): string * * @return string *

A string that contains only ASCII characters.

+ * + * @phpstan-param ASCII::*_LANGUAGE_CODE $language */ public static function to_ascii( string $str, @@ -839,13 +804,12 @@ public static function to_ascii( return ''; } + /** @phpstan-var ASCII::*_LANGUAGE_CODE - hack for phpstan */ $language = self::get_language($language); static $EXTRA_SYMBOLS_CACHE = null; - /** - * @var array> - */ + /** @var array> */ static $REPLACE_HELPER_CACHE = []; $cacheKey = $language . '-' . $replace_extra_symbols; @@ -1019,7 +983,6 @@ public static function to_ascii( } if ($use_transliterate) { - /** @noinspection ArgumentEqualsDefaultValueInspection */ $str = self::to_transliterate($str, null, false); } @@ -1061,9 +1024,9 @@ public static function to_filename( $str = (string) \preg_replace( [ - '/[^' . $fallback_char_escaped . '.\\-a-zA-Z0-9\\s]/', // 1) remove un-needed chars - '/[\\s]+/u', // 2) convert spaces to $fallback_char - '/[' . $fallback_char_escaped . ']+/u', // 3) remove double $fallback_char's + '/[^' . $fallback_char_escaped . '.\\-a-zA-Z\d\\s]/', // 1) remove un-needed chars + '/\s+/u', // 2) convert spaces to $fallback_char + '/[' . $fallback_char_escaped . ']+/u', // 3) remove double $fallback_char's ], [ '', @@ -1098,6 +1061,8 @@ public static function to_filename( * * @return string *

A string that has been converted to an URL slug.

+ * + * @phpstan-param ASCII::*_LANGUAGE_CODE $language */ public static function to_slugify( string $str, @@ -1178,19 +1143,13 @@ public static function to_transliterate( $unknown = '?', bool $strict = false ): string { - /** - * @var array|null - */ + /** @var array|null */ static $UTF8_TO_TRANSLIT = null; - /** - * null|\Transliterator - */ + /** null|\Transliterator */ static $TRANSLITERATOR = null; - /** - * @var bool|null - */ + /** @var bool|null */ static $SUPPORT_INTL = null; if ($str === '') { @@ -1225,9 +1184,7 @@ public static function to_transliterate( ) { if (!isset($TRANSLITERATOR)) { // INFO: see "*-Latin" rules via "transliterator_list_ids()" - /** - * @var \Transliterator - */ + /** @var \Transliterator */ $TRANSLITERATOR = \transliterator_create('NFKC; [:Nonspacing Mark:] Remove; NFKC; Any-Latin; Latin-ASCII;'); } @@ -1376,6 +1333,50 @@ public static function to_transliterate( return $str_tmp; } + /** + * WARNING: This method will return broken characters and is only for special cases. + * + * Convert a UTF-8 encoded string to a single-byte string suitable for + * functions that need the same string length after the conversion. + * + * The function simply uses (and updates) a tailored dynamic encoding + * (in/out map parameter) where non-ascii characters are remapped to + * the range [128-255] in order of appearance. + * + * Thus, it supports up to 128 different multibyte code points max over + * the whole set of strings sharing this encoding. + * + * Source: https://github.com/KEINOS/mb_levenshtein + * + * @param string $str

UTF-8 string to be converted to extended ASCII.

+ * @param array $map

Internal-Map of code points to ASCII characters.

+ * + * @return string + *

Mapped borken string.

+ * + * @phpstan-param array $map + */ + private static function to_ascii_remap_intern(string $str, array &$map): string + { + // find all utf-8 characters + $matches = []; + if (!\preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $str, $matches)) { + return $str; // plain ascii string + } + + // update the encoding map with the characters not already met + $mapCount = \count($map); + foreach ($matches[0] as $mbc) { + if (!isset($map[$mbc])) { + $map[$mbc] = \chr(128 + $mapCount); + ++$mapCount; + } + } + + // finally, remap non-ascii characters + return \strtr($str, $map); + } + /** * Get the language from a string. * diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php index d51f557a1..68c3f9d25 100644 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php +++ b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php @@ -1060,9 +1060,9 @@ 'Я' => 'Ya', 'я' => 'ya', ], - // Russian - Passport (2013), ICAO + // Russian - GOST 7.79-2000(B) // -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1 - 'ru__passport_2013' => [ + 'ru__gost_2000_b' => [ 'А' => 'A', 'а' => 'a', 'Б' => 'B', @@ -1075,8 +1075,8 @@ 'д' => 'd', 'Е' => 'E', 'е' => 'e', - 'Ё' => 'E', - 'ё' => 'e', + 'Ё' => 'Yo', + 'ё' => 'yo', 'Ж' => 'Zh', 'ж' => 'zh', 'З' => 'Z', @@ -1107,42 +1107,42 @@ 'у' => 'u', 'Ф' => 'F', 'ф' => 'f', - 'Х' => 'Kh', - 'х' => 'kh', - 'Ц' => 'Ts', - 'ц' => 'ts', + 'Х' => 'X', + 'х' => 'x', + 'Ц' => 'Cz', + 'ц' => 'cz', 'Ч' => 'Ch', 'ч' => 'ch', 'ш' => 'sh', 'Ш' => 'Sh', - 'Щ' => 'Shch', - 'щ' => 'shch', - 'Ъ' => 'Ie', - 'ъ' => 'ie', - 'Ы' => 'Y', - 'ы' => 'y', + 'Щ' => 'Shh', + 'щ' => 'shh', + 'Ъ' => '', + 'ъ' => '', + 'Ы' => 'Y\'', + 'ы' => 'y\'', 'Ь' => '', 'ь' => '', - 'Э' => 'E', - 'э' => 'e', - 'Ю' => 'Iu', - 'ю' => 'iu', - 'Я' => 'Ia', - 'я' => 'ia', - 'І' => '', - 'і' => '', - 'Ѳ' => '', - 'ѳ' => '', - 'Ѣ' => '', - 'ѣ' => '', - 'Ѵ' => '', - 'ѵ' => '', + 'Э' => 'E\'', + 'э' => 'e\'', + 'Ю' => 'Yu', + 'ю' => 'yu', + 'Я' => 'Ya', + 'я' => 'ya', + 'І' => 'I', + 'і' => 'i', + 'Ѳ' => 'Fh', + 'ѳ' => 'fh', + 'Ѣ' => 'Ye', + 'ѣ' => 'ye', + 'Ѵ' => 'Yh', + 'ѵ' => 'yh', 'Є' => '', 'є' => '', 'Ѥ' => '', 'ѥ' => '', - 'Ѕ' => '', - 'ѕ' => '', + 'Ѕ' => 'Js', + 'ѕ' => 'js', 'Ꙋ' => '', 'ꙋ' => '', 'Ѡ' => '', @@ -1162,9 +1162,9 @@ 'Ѱ' => '', 'ѱ' => '', ], - // Russian - GOST 7.79-2000(B) + // Russian - Passport (2013), ICAO // -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1 - 'ru__gost_2000_b' => [ + 'ru__passport_2013' => [ 'А' => 'A', 'а' => 'a', 'Б' => 'B', @@ -1177,8 +1177,8 @@ 'д' => 'd', 'Е' => 'E', 'е' => 'e', - 'Ё' => 'Yo', - 'ё' => 'yo', + 'Ё' => 'E', + 'ё' => 'e', 'Ж' => 'Zh', 'ж' => 'zh', 'З' => 'Z', @@ -1209,42 +1209,42 @@ 'у' => 'u', 'Ф' => 'F', 'ф' => 'f', - 'Х' => 'X', - 'х' => 'x', - 'Ц' => 'Cz', - 'ц' => 'cz', + 'Х' => 'Kh', + 'х' => 'kh', + 'Ц' => 'Ts', + 'ц' => 'ts', 'Ч' => 'Ch', 'ч' => 'ch', 'ш' => 'sh', 'Ш' => 'Sh', - 'Щ' => 'Shh', - 'щ' => 'shh', - 'Ъ' => '', - 'ъ' => '', - 'Ы' => 'Y\'', - 'ы' => 'y\'', + 'Щ' => 'Shch', + 'щ' => 'shch', + 'Ъ' => 'Ie', + 'ъ' => 'ie', + 'Ы' => 'Y', + 'ы' => 'y', 'Ь' => '', 'ь' => '', - 'Э' => 'E\'', - 'э' => 'e\'', - 'Ю' => 'Yu', - 'ю' => 'yu', - 'Я' => 'Ya', - 'я' => 'ya', - 'І' => 'I', - 'і' => 'i', - 'Ѳ' => 'Fh', - 'ѳ' => 'fh', - 'Ѣ' => 'Ye', - 'ѣ' => 'ye', - 'Ѵ' => 'Yh', - 'ѵ' => 'yh', + 'Э' => 'E', + 'э' => 'e', + 'Ю' => 'Iu', + 'ю' => 'iu', + 'Я' => 'Ia', + 'я' => 'ia', + 'І' => '', + 'і' => '', + 'Ѳ' => '', + 'ѳ' => '', + 'Ѣ' => '', + 'ѣ' => '', + 'Ѵ' => '', + 'ѵ' => '', 'Є' => '', 'є' => '', 'Ѥ' => '', 'ѥ' => '', - 'Ѕ' => 'Js', - 'ѕ' => 'js', + 'Ѕ' => '', + 'ѕ' => '', 'Ꙋ' => '', 'ꙋ' => '', 'Ѡ' => '', @@ -1265,15 +1265,32 @@ 'ѱ' => '', ], // Ukrainian + // -> https://zakon.rada.gov.ua/laws/show/55-2010-%D0%BF?lang=en 'uk' => [ + 'Г' => 'H', + 'г' => 'h', + 'Ґ' => 'G', + 'ґ' => 'g', 'Є' => 'Ye', 'є' => 'ye', + 'И' => 'Y', + 'и' => 'y', 'І' => 'I', 'і' => 'i', 'Ї' => 'Yi', 'ї' => 'yi', - 'Ґ' => 'G', - 'ґ' => 'g', + 'Й' => 'Y', + 'й' => 'y', + 'Х' => 'Kh', + 'х' => 'kh', + 'Ц' => 'Ts', + 'ц' => 'ts', + 'Ч' => 'Ch', + 'ч' => 'ch', + 'Ш' => 'Sh', + 'ш' => 'sh', + 'Щ' => 'Shch', + 'щ' => 'shch', ], // Kazakh 'kk' => [ @@ -1602,10 +1619,10 @@ 'fa' => [ 'ا' => 'a', 'ب' => 'b', - 'پ' => 'b', + 'پ' => 'p', 'ت' => 't', 'ث' => 's', - 'ج' => 'g', + 'ج' => 'j', 'چ' => 'ch', 'ح' => 'h', 'خ' => 'kh', @@ -2555,6 +2572,8 @@ 'j̄' => 'j', 'J̃' => 'J', 'j̃' => 'j', + 'Й' => 'i', + 'й' => 'i', 'ĸ' => 'k', 'Ĺ' => 'L', 'Ľ' => 'L', @@ -2810,6 +2829,8 @@ 'ȳ' => 'y', 'Ỹ' => 'Y', 'ỹ' => 'y', + 'Щ' => 'Shh', + 'щ' => 'shh', 'Ź' => 'Z', 'ź' => 'z', 'Z̀' => 'Z', diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php index 426d84a4d..afe31ae2c 100644 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php +++ b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php @@ -199,8 +199,8 @@ '&' => ' i ', '+' => ' plus ', ], - // Russian - Passport (2013), ICAO - 'ru__passport_2013' => [ + // Russian - GOST 7.79-2000(B) + 'ru__gost_2000_b' => [ '=' => ' ravnyj ', '%' => ' procent ', '∑' => ' summa ', @@ -210,8 +210,8 @@ '&' => ' i ', '+' => ' plus ', ], - // Russian - GOST 7.79-2000(B) - 'ru__gost_2000_b' => [ + // Russian - Passport (2013), ICAO + 'ru__passport_2013' => [ '=' => ' ravnyj ', '%' => ' procent ', '∑' => ' summa ', diff --git a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php index a6345f213..da81ae236 100644 --- a/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php +++ b/lam/lib/3rdParty/composer/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php @@ -31,8 +31,8 @@ 'fi' => 1, 'ka' => 1, 'ru' => 1, - 'ru__passport_2013' => 1, 'ru__gost_2000_b' => 1, + 'ru__passport_2013' => 1, 'uk' => 1, 'kk' => 1, 'cs' => 1, diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/Dockerfile b/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/Dockerfile new file mode 100644 index 000000000..ff0f11e6c --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/Dockerfile @@ -0,0 +1,23 @@ +FROM ubuntu:latest +LABEL maintainer="Webklex " + +RUN apt-get update +RUN apt-get upgrade -y +RUN apt-get install -y sudo dovecot-imapd + +ENV LIVE_MAILBOX=true +ENV LIVE_MAILBOX_HOST=mail.example.local +ENV LIVE_MAILBOX_PORT=993 +ENV LIVE_MAILBOX_ENCRYPTION=ssl +ENV LIVE_MAILBOX_VALIDATE_CERT=true +ENV LIVE_MAILBOX_USERNAME=root@example.local +ENV LIVE_MAILBOX_PASSWORD=foobar +ENV LIVE_MAILBOX_QUOTA_SUPPORT=true + +EXPOSE 993 + +ADD dovecot_setup.sh /root/dovecot_setup.sh +RUN chmod +x /root/dovecot_setup.sh + +CMD ["/bin/bash", "-c", "/root/dovecot_setup.sh && tail -f /dev/null"] + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/dovecot_setup.sh b/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/dovecot_setup.sh new file mode 100644 index 000000000..25a519283 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/.github/docker/dovecot_setup.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +set -ex + +sudo apt-get -q update +sudo apt-get -q -y install dovecot-imapd + +{ + echo "127.0.0.1 $LIVE_MAILBOX_HOST" +} | sudo tee -a /etc/hosts + +SSL_CERT="/etc/ssl/certs/dovecot.crt" +SSL_KEY="/etc/ssl/private/dovecot.key" + +sudo openssl req -new -x509 -days 3 -nodes \ + -out "$SSL_CERT" \ + -keyout "$SSL_KEY" \ + -subj "/C=EU/ST=Europe/L=Home/O=Webklex/OU=Webklex DEV/CN=""$LIVE_MAILBOX_HOST" + +sudo chown root:dovecot "$SSL_CERT" "$SSL_KEY" +sudo chmod 0440 "$SSL_CERT" +sudo chmod 0400 "$SSL_KEY" + +DOVECOT_CONF="/etc/dovecot/local.conf" +MAIL_CONF="/etc/dovecot/conf.d/10-mail.conf" +IMAP_CONF="/etc/dovecot/conf.d/20-imap.conf" +QUOTA_CONF="/etc/dovecot/conf.d/90-quota.conf" +sudo touch "$DOVECOT_CONF" "$MAIL_CONF" "$IMAP_CONF" "$QUOTA_CONF" +sudo chown root:dovecot "$DOVECOT_CONF" "$MAIL_CONF" "$IMAP_CONF" "$QUOTA_CONF" +sudo chmod 0640 "$DOVECOT_CONF" "$MAIL_CONF" "$IMAP_CONF" "$QUOTA_CONF" + +{ + echo "ssl = required" + echo "disable_plaintext_auth = yes" + echo "ssl_cert = <""$SSL_CERT" + echo "ssl_key = <""$SSL_KEY" + echo "ssl_protocols = !SSLv2 !SSLv3" + echo "ssl_cipher_list = AES128+EECDH:AES128+EDH" +} | sudo tee -a "$DOVECOT_CONF" + +{ + echo "mail_plugins = \$mail_plugins quota" +} | sudo tee -a "$MAIL_CONF" + +{ + echo "protocol imap {" + echo " mail_plugins = \$mail_plugins imap_quota" + echo "}" +} | sudo tee -a "$IMAP_CONF" + +{ + echo "plugin {" + echo " quota = maildir:User quota" + echo " quota_rule = *:storage=1G" + echo "}" +} | sudo tee -a "$QUOTA_CONF" + +sudo useradd --create-home --shell /bin/false "$LIVE_MAILBOX_USERNAME" +echo "$LIVE_MAILBOX_USERNAME"":""$LIVE_MAILBOX_PASSWORD" | sudo chpasswd + +sudo service dovecot restart + +sudo doveadm auth test -x service=imap "$LIVE_MAILBOX_USERNAME" "$LIVE_MAILBOX_PASSWORD" \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/.github/workflows/tests.yaml b/lam/lib/3rdParty/composer/webklex/php-imap/.github/workflows/tests.yaml new file mode 100644 index 000000000..b441efd3d --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/.github/workflows/tests.yaml @@ -0,0 +1,50 @@ +name: Tests + +on: + push: + pull_request: + schedule: + - cron: '0 0 * * *' + +permissions: + contents: read + +jobs: + phpunit: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: ['8.0', 8.1, 8.2] + + name: PHP ${{ matrix.php }} + + env: + LIVE_MAILBOX: true + LIVE_MAILBOX_DEBUG: true + LIVE_MAILBOX_HOST: mail.example.local + LIVE_MAILBOX_PORT: 993 + LIVE_MAILBOX_USERNAME: root@example.local + LIVE_MAILBOX_ENCRYPTION: ssl + LIVE_MAILBOX_PASSWORD: foobar + LIVE_MAILBOX_QUOTA_SUPPORT: true + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: openssl, json, mbstring, iconv, fileinfo, libxml, zip + coverage: none + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction --no-progress + + - run: "sh .github/docker/dovecot_setup.sh" + + - name: Execute tests + run: vendor/bin/phpunit \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/.gitignore b/lam/lib/3rdParty/composer/webklex/php-imap/.gitignore index 77d608c33..d1816ad98 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/.gitignore +++ b/lam/lib/3rdParty/composer/webklex/php-imap/.gitignore @@ -2,3 +2,6 @@ vendor composer.lock .idea /build/ +test.php +.phpunit.result.cache +phpunit.xml \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/.travis.yml b/lam/lib/3rdParty/composer/webklex/php-imap/.travis.yml deleted file mode 100644 index 26e564efd..000000000 --- a/lam/lib/3rdParty/composer/webklex/php-imap/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: php - -os: linux -dist: xenial - -php: - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - hhvm - -jobs: - fast_finish: true - allow_failures: - - php: 7.3 - - php: 7.4 - - php: hhvm - -before_install: - - COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-source --no-interaction --dev - -install: - - COMPOSER_MEMORY_LIMIT=-1 composer install --no-interaction - -script: - - ./vendor/bin/phpunit - -notifications: - email: - on_success: always - on_failure: always diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/CHANGELOG.md b/lam/lib/3rdParty/composer/webklex/php-imap/CHANGELOG.md index 48b41c471..6e7757108 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/CHANGELOG.md +++ b/lam/lib/3rdParty/composer/webklex/php-imap/CHANGELOG.md @@ -6,15 +6,169 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ## [UNRELEASED] ### Fixed -- NaN +- Error token length mismatch in `ImapProtocol::readResponse` #400 +- Attachment name parsing fixed #410 #421 (thanks @nuernbergerA) +- Additional Attachment name fallback added to prevent missing attachments +- Attachment id is now static (based on the raw part content) and now longer random +- Always parse the attachment description if it is available ### Added -- NaN +- Attachment content hash added ### Breaking changes - NaN +## [5.5.0] - 2023-06-28 +### Fixed +- Error token length mismatch in `ImapProtocol::readResponse` #400 +- Attachment name parsing fixed #410 #421 (thanks @nuernbergerA) +- Additional Attachment name fallback added to prevent missing attachments +- Attachment id is now static (based on the raw part content) and now longer random +- Always parse the attachment description if it is available + +### Added +- Attachment content hash added + + +## [5.4.0] - 2023-06-24 +### Fixed +- Legacy protocol support fixed (object to array conversion) #411 +- Header value decoding improved #410 +- Protocol exception handling improved (bad response message added) #408 +- Prevent fetching singular rfc partials from running indefinitely #407 +- Subject with colon ";" is truncated #401 +- Catching and handling iconv decoding exception #397 + +### Added +- Additional timestamp formats added #198 #392 (thanks @esk-ap) + + +## [5.3.0] - Security patch - 2023-06-20 +### Fixed +- Potential RCE through path traversal fixed #414 (special thanks @angelej) + +### Security Impact and Mitigation +Impacted are all versions below v5.3.0. +If possible, update to >= v5.3.0 as soon as possible. Impacted was the `Attachment::save` +method which could be used to write files to the local filesystem. The path was not +properly sanitized and could be used to write files to arbitrary locations. + +However, the `Attachment::save` method is not used by default and has to be called +manually. If you are using this method without providing a sanitized path, you are +affected by this vulnerability. +If you are not using this method or are providing a sanitized path, you are not affected +by this vulnerability and no immediate action is required. + +If you have any questions, please feel welcome to join this issue: https://github.com/Webklex/php-imap/issues/416 +#### Timeline +- 17.06.23 21:30: Vulnerability reported +- 18.06.23 19:14: Vulnerability confirmed +- 19.06.23 18:41: Vulnerability fixed via PR #414 +- 20.06.23 13:45: Security patch released +- 21.06.23 20:48: CVE-2023-35169 got assigned +- 21.06.23 20:58: Advisory released https://github.com/Webklex/php-imap/security/advisories/GHSA-47p7-xfcc-4pv9 + + +## [5.2.0] - 2023-04-11 +### Fixed +- Use all available methods to detect the attachment extension instead of just one +- Allow the `LIST` command response to be empty #393 +- Initialize folder children attributes on class initialization + +### Added +- Soft fail option added to all folder fetching methods. If soft fail is enabled, the method will return an empty collection instead of throwing an exception if the folder doesn't exist + + +## [5.1.0] - 2023-03-16 +### Fixed +- IMAP Quota root command fixed +- Prevent line-breaks in folder path caused by special chars +- Partial fix for #362 (allow overview response to be empty) +- `Message::setConfig()` config parameter type set to array +- Reset the protocol uid cache if the session gets expunged +- Set the "seen" flag only if the flag isn't set and the fetch option isn't `IMAP::FT_PEEK` +- `Message::is()` date comparison fixed +- `Message::$client` could not be set to null +- `in_reply_to` and `references` parsing fixed +- Prevent message body parser from injecting empty lines +- Don't parse regular inline message parts without name or filename as attachment +- `Message::hasTextBody()` and `Message::hasHtmlBody()` should return `false` if the body is empty +- Imap-Protocol "empty response" detection extended to catch an empty response caused by a broken resource stream +- `iconv_mime_decode()` is now used with `ICONV_MIME_DECODE_CONTINUE_ON_ERROR` to prevent the decoding from failing +- Date decoding rules extended to support more date formats +- Unset the currently active folder if it gets deleted (prevent infinite loop) +- Attachment name and filename parsing fixed and improved to support more formats +- Check if the next uid is available (after copying or moving a message) before fetching it #381 +- Default pagination `$total` attribute value set to 0 #385 (thanks @hhniao) +- Use attachment ID as fallback filename for saving an attachment +- Address decoding error detection added #388 + +### Added +- Extended UTF-7 support added (RFC2060) #383 +- `Protocol::sizes()` support added (fetch the message byte size via RFC822.SIZE). Accessible through `Message::getSize()` #379 (thanks @didi1357) +- `Message::hasFlag()` method added to check if a message has a specific flag +- `Message::getConfig()` method added to get the current message configuration +- `Folder::select()` method added to select a folder +- `Message::getAvailableFlags()` method added to get all available flags +- Live mailbox and fixture tests added +- `Attribute::map()` method added to map all attribute values +- `Header::has()` method added to check if a header attribute / value exist +- All part attributes are now accessible via linked attribute +- Restore a message from string `Message::fromString()` + + +## [5.0.1] - 2023-03-01 +### Fixed +- More unique ID generation to prevent multiple attachments with same ID #363 (thanks @Guite) +- Not all attachments are pushed to the collection #372 (thanks @AdrianKuriata) +- Partial fix for #362 (allow search response to be empty) +- Unsafe usage of switch case. #354 #366 (thanks @shuergab) +- Fix use of ST_MSGN as sequence method #356 (thanks @gioid) +- Prevent infinite loop in ImapProtocol #316 (thanks @thin-k-design) + + +## [5.0.0] - 2023-01-18 +### Fixed +- The message uid and message number will only be fetched if accessed and wasn't previously set #326 #285 (thanks @szymekjanaczek) +- Fix undefined attachment name when headers use "filename*=" format #301 (thanks @JulienChavee) +- Fixed `ImapProtocol::logout` always throws 'not connected' Exception after upgraded to 4.1.2 #351 +- Protocol interface and methods unified +- Strict attribute and return types introduced where ever possible +- Parallel messages during idle #338 +- Idle timeout / stale resource stream issue fixed +- Syntax updated to support php 8 features +- Get the attachment file extension from the filename if no mimetype detection library is available +- Prevent the structure parsing from parsing an empty part +- Convert all header keys to their lower case representation +- Restructure the decode function #355 (thanks @istid) + +### Added +- Unit tests added #347 #242 (thanks @sergiy-petrov, @boekkooi-lengoo) +- `Client::clone()` method added to clone a client instance +- Save an entire message (including its headers) `Message::save()` +- Restore a message from a local or remote file `Message::fromFile()` +- Protocol resource stream accessor added `Protocol::getStream()` +- Protocol resource stream meta data accessor added `Protocol::meta()` +- ImapProtocol resource stream reset method added `ImapProtocol::reset()` +- Protocol `Response::class` introduced to handle and unify all protocol requests +- Static mask config accessor added `ClientManager::getMask()` added +- An `Attribute::class` instance can be treated as array +- Get the current client account configuration via `Client::getConfig()` +- Delete a folder via `Client::deleteFolder()` + +### Breaking changes +- PHP ^8.0.2 required +- `nesbot/carbon` version bumped to ^2.62.1 +- `phpunit/phpunit` version bumped to ^9.5.10 +- `Header::get()` always returns an `Attribute::class` instance +- `Attribute::class` accessor methods renamed to shorten their names and improve the readability +- All protocol methods that used to return `array|bool` will now always return a `Response::class` instance. +- `ResponseException::class` gets thrown if a response is empty or contains errors +- Message client is optional and can be null (e.g. if used in combination with `Message::fromFile()`) +- The message text or html body is now "" if its empty and not `null` + + ## [4.1.2] - 2022-12-14 ### Fixed - Attachment ID can return an empty value #318 diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/README.md b/lam/lib/3rdParty/composer/webklex/php-imap/README.md index 3aef3a4b6..c110d48f3 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/README.md +++ b/lam/lib/3rdParty/composer/webklex/php-imap/README.md @@ -4,7 +4,6 @@ [![Latest release on Packagist][ico-release]][link-packagist] [![Latest prerelease on Packagist][ico-prerelease]][link-packagist] [![Software License][ico-license]][link-license] -[![Build Status][ico-travis]][link-scrutinizer] [![Total Downloads][ico-downloads]][link-downloads] [![Hits][ico-hits]][link-hits] [![Discord][ico-discord]][link-discord] @@ -26,7 +25,10 @@ Discord: [discord.gg/rd4cN9h6][link-discord] ## Table of Contents - [Documentations](#documentations) +- [Compatibility](#compatibility) - [Basic usage example](#basic-usage-example) +- [Sponsors](#sponsors) +- [Testing](#testing) - [Known issues](#known-issues) - [Support](#support) - [Features & pull requests](#features--pull-requests) @@ -40,14 +42,25 @@ Discord: [discord.gg/rd4cN9h6][link-discord] - Core documentation: [php-imap.com](https://www.php-imap.com/) +## Compatibility +| Version | PHP 5.6 | PHP 7 | PHP 8 | +|:--------|:-------:|:-----:|:-----:| +| v5.x | / | / | X | +| v4.x | / | X | X | +| v3.x | / | X | / | +| v2.x | X | X | / | +| v1.x | X | / | / | + ## Basic usage example This is a basic example, which will echo out all Mails within all imap folders and will move every message into INBOX.read. Please be aware that this should not be -tested in real life and is only meant to gives an impression on how things work. +tested in real life and is only meant to give an impression on how things work. ```php use Webklex\PHPIMAP\ClientManager; +require_once "vendor/autoload.php"; + $cm = new ClientManager('path/to/config/imap.php'); /** @var \Webklex\PHPIMAP\Client $client */ @@ -84,17 +97,74 @@ foreach($folders as $folder){ } ``` +## Sponsors +[![Feline][ico-sponsor-feline]][link-sponsor-feline] + + +## Testing +To run the tests, please execute the following command: +```bash +composer test +``` + +### Quick-Test / Static Test +To disable all test which require a live mailbox, please copy the `phpunit.xml.dist` to `phpunit.xml` and adjust the configuration: +```xml + + + +``` + +### Full-Test / Live Mailbox Test +To run all tests, you need to provide a valid imap configuration. + +To provide a valid imap configuration, please copy the `phpunit.xml.dist` to `phpunit.xml` and adjust the configuration: +```xml + + + + + + + + + + + +``` + +The test account should **not** contain any important data, as it will be deleted during the test. +Furthermore, the test account should be able to create new folders, move messages and should **not** be used by any other +application during the test. + +It's recommended to use a dedicated test account for this purpose. You can use the provided `Dockerfile` to create an imap server used for testing purposes. + +Build the docker image: +```bash +cd .github/docker + +docker build -t php-imap-server . +``` +Run the docker image: +```bash +docker run --name imap-server -p 993:993 --rm -d php-imap-server +``` +Stop the docker image: +```bash +docker stop imap-server +``` + ### Known issues -| Error | Solution | -| ------------------------------------------------------------------------- | ---------------------------------------------------------- | -| Kerberos error: No credentials cache file found (try running kinit) (...) | Uncomment "DISABLE_AUTHENTICATOR" inside your config and use the `legacy-imap` protocol | +| Error | Solution | +|:---------------------------------------------------------------------------|:----------------------------------------------------------------------------------------| +| Kerberos error: No credentials cache file found (try running kinit) (...) | Uncomment "DISABLE_AUTHENTICATOR" inside your config and use the `legacy-imap` protocol | ## Support If you encounter any problems or if you find a bug, please don't hesitate to create a new [issue](https://github.com/Webklex/php-imap/issues). -However please be aware that it might take some time to get an answer. -Off topic, rude or abusive issues will be deleted without any notice. +However, please be aware that it might take some time to get an answer. +Off-topic, rude or abusive issues will be deleted without any notice. If you need **commercial** support, feel free to send me a mail at github@webklex.com. @@ -116,7 +186,7 @@ echo 'your php code...'; ## Features & pull requests -Everyone can contribute to this project. Every pull request will be considered but it can also happen to be declined. +Everyone can contribute to this project. Every pull request will be considered, but it can also happen to be declined. To prevent unnecessary work, please consider to create a [feature issue](https://github.com/Webklex/php-imap/issues/new?template=feature_request.md) first, if you're planning to do bigger changes. Of course, you can also create a new [feature issue](https://github.com/Webklex/php-imap/issues/new?template=feature_request.md) if you're just wishing a feature ;) @@ -142,26 +212,21 @@ The MIT License (MIT). Please see [License File][link-license] for more informat [ico-release]: https://img.shields.io/packagist/v/Webklex/php-imap.svg?style=flat-square&label=version [ico-prerelease]: https://img.shields.io/github/v/release/webklex/php-imap?include_prereleases&style=flat-square&label=pre-release [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square -[ico-travis]: https://img.shields.io/travis/Webklex/php-imap/master.svg?style=flat-square -[ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/Webklex/php-imap.svg?style=flat-square -[ico-code-quality]: https://img.shields.io/scrutinizer/g/Webklex/php-imap.svg?style=flat-square [ico-downloads]: https://img.shields.io/packagist/dt/Webklex/php-imap.svg?style=flat-square -[ico-build]: https://img.shields.io/scrutinizer/build/g/Webklex/php-imap/master?style=flat-square -[ico-quality]: https://img.shields.io/scrutinizer/quality/g/Webklex/php-imap/master?style=flat-square [ico-hits]: https://hits.webklex.com/svg/webklex/php-imap [ico-snyk]: https://snyk-widget.herokuapp.com/badge/composer/webklex/php-imap/badge.svg [ico-discord]: https://img.shields.io/static/v1?label=discord&message=open&color=5865f2&style=flat-square [link-packagist]: https://packagist.org/packages/Webklex/php-imap -[link-travis]: https://travis-ci.org/Webklex/php-imap -[link-scrutinizer]: https://scrutinizer-ci.com/g/Webklex/php-imap/code-structure -[link-code-quality]: https://scrutinizer-ci.com/g/Webklex/php-imap [link-downloads]: https://packagist.org/packages/Webklex/php-imap [link-author]: https://github.com/webklex [link-contributors]: https://github.com/Webklex/php-imap/graphs/contributors [link-license]: https://github.com/Webklex/php-imap/blob/master/LICENSE [link-changelog]: https://github.com/Webklex/php-imap/blob/master/CHANGELOG.md -[link-jetbrains]: https://www.jetbrains.com [link-hits]: https://hits.webklex.com [link-snyk]: https://snyk.io/vuln/composer:webklex%2Fphp-imap [link-discord]: https://discord.gg/rd4cN9h6 + + +[ico-sponsor-feline]: https://cdn.feline.dk/public/feline.png +[link-sponsor-feline]: https://www.feline.dk \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/composer.json b/lam/lib/3rdParty/composer/webklex/php-imap/composer.json index 651044800..37efc1c5e 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/composer.json +++ b/lam/lib/3rdParty/composer/webklex/php-imap/composer.json @@ -19,21 +19,24 @@ } ], "require": { - "php": ">=7.0.0", + "php": "^8.0.2", "ext-openssl": "*", "ext-json": "*", "ext-mbstring": "*", "ext-iconv": "*", + "ext-libxml": "*", + "ext-zip": "*", "ext-fileinfo": "*", - "nesbot/carbon": ">=1.0", + "nesbot/carbon": "^2.62.1", "symfony/http-foundation": ">=2.8.0", "illuminate/pagination": ">=5.0.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^9.5.10" }, "suggest": { - "symfony/mime": "Recomended for better extension support" + "symfony/mime": "Recomended for better extension support", + "symfony/var-dumper": "Usefull tool for debugging" }, "autoload": { "psr-4": { diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_attachment_mask.php b/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_attachment_mask.php index 32b7b91ef..5a6323a35 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_attachment_mask.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_attachment_mask.php @@ -16,7 +16,7 @@ class CustomAttachmentMask extends \Webklex\PHPIMAP\Support\Masks\AttachmentMask * New custom method which can be called through a mask * @return string */ - public function token(){ + public function token(): string { return implode('-', [$this->id, $this->getMessage()->getUid(), $this->name]); } @@ -24,7 +24,7 @@ public function token(){ * Custom attachment saving method * @return bool */ - public function custom_save() { + public function custom_save(): bool { $path = "foo".DIRECTORY_SEPARATOR."bar".DIRECTORY_SEPARATOR; $filename = $this->token(); diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_message_mask.php b/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_message_mask.php index 25d056676..187eeed4c 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_message_mask.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/examples/custom_message_mask.php @@ -16,7 +16,7 @@ class CustomMessageMask extends \Webklex\PHPIMAP\Support\Masks\MessageMask { * New custom method which can be called through a mask * @return string */ - public function token(){ + public function token(): string { return implode('-', [$this->message_id, $this->uid, $this->message_no]); } @@ -24,7 +24,7 @@ public function token(){ * Get number of message attachments * @return integer */ - public function getAttachmentCount() { + public function getAttachmentCount(): int { return $this->getAttachments()->count(); } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml b/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml deleted file mode 100644 index bfbb0b093..000000000 --- a/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - tests - - - - - src/ - - - - - - - - - - - - - \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml.dist b/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml.dist new file mode 100644 index 000000000..02d56a897 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/phpunit.xml.dist @@ -0,0 +1,35 @@ + + + + + src/ + + + + + + + + + + tests + tests/fixtures + tests/issues + tests/live + + + + + + + + + + + + + + + + + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Address.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Address.php index 96e48d94b..b45c72dec 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Address.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Address.php @@ -27,22 +27,22 @@ class Address { * @var string $mail * @var string $full */ - public $personal = ""; - public $mailbox = ""; - public $host = ""; - public $mail = ""; - public $full = ""; + public string $personal = ""; + public string $mailbox = ""; + public string $host = ""; + public string $mail = ""; + public string $full = ""; /** * Address constructor. - * @param object $object + * @param object $object */ - public function __construct($object) { - if (property_exists($object, "personal")){ $this->personal = $object->personal; } - if (property_exists($object, "mailbox")){ $this->mailbox = $object->mailbox; } - if (property_exists($object, "host")){ $this->host = $object->host; } - if (property_exists($object, "mail")){ $this->mail = $object->mail; } - if (property_exists($object, "full")){ $this->full = $object->full; } + public function __construct(object $object) { + if (property_exists($object, "personal")){ $this->personal = $object->personal ?? ''; } + if (property_exists($object, "mailbox")){ $this->mailbox = $object->mailbox ?? ''; } + if (property_exists($object, "host")){ $this->host = $object->host ?? ''; } + if (property_exists($object, "mail")){ $this->mail = $object->mail ?? ''; } + if (property_exists($object, "full")){ $this->full = $object->full ?? ''; } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Attachment.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Attachment.php index a7c74969b..15b83f636 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Attachment.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Attachment.php @@ -28,8 +28,11 @@ * @property string type * @property string content_type * @property string id + * @property string hash * @property string name - * @property string disposition + * @property string description + * @property string filename + * @property ?string disposition * @property string img_src * * @method integer getPartNumber() @@ -42,6 +45,8 @@ * @method string setContentType(string $content_type) * @method string getId() * @method string setId(string $id) + * @method string getHash() + * @method string setHash(string $hash) * @method string getSize() * @method string setSize(integer $size) * @method string getName() @@ -54,33 +59,36 @@ class Attachment { /** * @var Message $oMessage */ - protected $oMessage; + protected Message $oMessage; /** * Used config * * @var array $config */ - protected $config = []; + protected array $config = []; /** @var Part $part */ - protected $part; + protected Part $part; /** * Attribute holder * * @var array $attributes */ - protected $attributes = [ - 'content' => null, - 'type' => null, - 'part_number' => 0, + protected array $attributes = [ + 'content' => null, + 'hash' => null, + 'type' => null, + 'part_number' => 0, 'content_type' => null, - 'id' => null, - 'name' => null, - 'disposition' => null, - 'img_src' => null, - 'size' => null, + 'id' => null, + 'name' => null, + 'filename' => null, + 'description' => null, + 'disposition' => null, + 'img_src' => null, + 'size' => null, ]; /** @@ -88,12 +96,12 @@ class Attachment { * * @var string $mask */ - protected $mask = AttachmentMask::class; + protected string $mask = AttachmentMask::class; /** * Attachment constructor. - * @param Message $oMessage - * @param Part $part + * @param Message $oMessage + * @param Part $part */ public function __construct(Message $oMessage, Part $part) { $this->config = ClientManager::get('options'); @@ -102,9 +110,16 @@ public function __construct(Message $oMessage, Part $part) { $this->part = $part; $this->part_number = $part->part_number; - $default_mask = $this->oMessage->getClient()->getDefaultAttachmentMask(); - if($default_mask != null) { - $this->mask = $default_mask; + if ($this->oMessage->getClient()) { + $default_mask = $this->oMessage->getClient()?->getDefaultAttachmentMask(); + if ($default_mask != null) { + $this->mask = $default_mask; + } + } else { + $default_mask = ClientManager::getMask("attachment"); + if ($default_mask != "") { + $this->mask = $default_mask; + } } $this->findType(); @@ -120,15 +135,15 @@ public function __construct(Message $oMessage, Part $part) { * @throws MethodNotFoundException */ public function __call(string $method, array $arguments) { - if(strtolower(substr($method, 0, 3)) === 'get') { + if (strtolower(substr($method, 0, 3)) === 'get') { $name = Str::snake(substr($method, 3)); - if(isset($this->attributes[$name])) { + if (isset($this->attributes[$name])) { return $this->attributes[$name]; } return null; - }elseif (strtolower(substr($method, 0, 3)) === 'set') { + } elseif (strtolower(substr($method, 0, 3)) === 'set') { $name = Str::snake(substr($method, 3)); $this->attributes[$name] = array_pop($arguments); @@ -136,7 +151,7 @@ public function __call(string $method, array $arguments) { return $this->attributes[$name]; } - throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported'); + throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported'); } /** @@ -159,7 +174,7 @@ public function __set($name, $value) { * @return mixed|null */ public function __get($name) { - if(isset($this->attributes[$name])) { + if (isset($this->attributes[$name])) { return $this->attributes[$name]; } @@ -169,72 +184,84 @@ public function __get($name) { /** * Determine the structure type */ - protected function findType() { - switch ($this->part->type) { - case IMAP::ATTACHMENT_TYPE_MESSAGE: - $this->type = 'message'; - break; - case IMAP::ATTACHMENT_TYPE_APPLICATION: - $this->type = 'application'; - break; - case IMAP::ATTACHMENT_TYPE_AUDIO: - $this->type = 'audio'; - break; - case IMAP::ATTACHMENT_TYPE_IMAGE: - $this->type = 'image'; - break; - case IMAP::ATTACHMENT_TYPE_VIDEO: - $this->type = 'video'; - break; - case IMAP::ATTACHMENT_TYPE_MODEL: - $this->type = 'model'; - break; - case IMAP::ATTACHMENT_TYPE_TEXT: - $this->type = 'text'; - break; - case IMAP::ATTACHMENT_TYPE_MULTIPART: - $this->type = 'multipart'; - break; - default: - $this->type = 'other'; - break; - } + protected function findType(): void { + $this->type = match ($this->part->type) { + IMAP::ATTACHMENT_TYPE_MESSAGE => 'message', + IMAP::ATTACHMENT_TYPE_APPLICATION => 'application', + IMAP::ATTACHMENT_TYPE_AUDIO => 'audio', + IMAP::ATTACHMENT_TYPE_IMAGE => 'image', + IMAP::ATTACHMENT_TYPE_VIDEO => 'video', + IMAP::ATTACHMENT_TYPE_MODEL => 'model', + IMAP::ATTACHMENT_TYPE_TEXT => 'text', + IMAP::ATTACHMENT_TYPE_MULTIPART => 'multipart', + default => 'other', + }; } /** * Fetch the given attachment */ - protected function fetch() { - + protected function fetch(): void { $content = $this->part->content; $this->content_type = $this->part->content_type; $this->content = $this->oMessage->decodeString($content, $this->part->encoding); + // Create a hash of the raw part - this can be used to identify the attachment in the message context. However, + // it is not guaranteed to be unique and collisions are possible. + // Some additional online resources: + // - https://en.wikipedia.org/wiki/Hash_collision + // - https://www.php.net/manual/en/function.hash.php + // - https://php.watch/articles/php-hash-benchmark + // Benchmark speeds: + // -xxh3 ~15.19(GB/s) (requires php-xxhash extension or >= php8.1) + // -crc32c ~14.12(GB/s) + // -sha256 ~0.25(GB/s) + // xxh3 would be nice to use, because of its extra speed and 32 instead of 8 bytes, but it is not compatible with + // php < 8.1. crc32c is the next fastest and is compatible with php >= 5.1. sha256 is the slowest, but is compatible + // with php >= 5.1 and is the most likely to be unique. crc32c is the best compromise between speed and uniqueness. + // Unique enough for our purposes, but not so slow that it could be a bottleneck. + $this->hash = hash("crc32c", $this->part->getHeader()->raw."\r\n\r\n".$this->part->content); + if (($id = $this->part->id) !== null) { $this->id = str_replace(['<', '>'], '', $id); - }else{ - $this->id = hash("sha256", (string)microtime(true)); + }else { + $this->id = $this->hash; } $this->size = $this->part->bytes; $this->disposition = $this->part->disposition; if (($filename = $this->part->filename) !== null) { - $this->setName($filename); - } elseif (($name = $this->part->name) !== null) { - $this->setName($name); - }else { - $this->setName("undefined"); + $this->filename = $this->decodeName($filename); + } + + if (($description = $this->part->description) !== null) { + $this->description = $this->part->getHeader()->decode($description); + } + + if (($name = $this->part->name) !== null) { + $this->name = $this->decodeName($name); } if (IMAP::ATTACHMENT_TYPE_MESSAGE == $this->part->type) { if ($this->part->ifdescription) { - $this->setName($this->part->description); - } else { - $this->setName($this->part->subtype); + if (!$this->name) { + $this->name = $this->part->description; + } + } else if (!$this->name) { + $this->name = $this->part->subtype; } } + $this->attributes = array_merge($this->part->getHeader()->getAttributes(), $this->attributes); + + if (!$this->filename) { + $this->filename = $this->hash; + } + + if (!$this->name && $this->filename != "") { + $this->name = $this->filename; + } } /** @@ -244,25 +271,44 @@ protected function fetch() { * * @return boolean */ - public function save(string $path, $filename = null): bool { - $filename = $filename ?: $this->getName(); + public function save(string $path, ?string $filename = null): bool { + $filename = $filename ? $this->decodeName($filename) : $this->filename; - return file_put_contents($path.$filename, $this->getContent()) !== false; + return file_put_contents($path . DIRECTORY_SEPARATOR . $filename, $this->getContent()) !== false; } /** - * Set the attachment name and try to decode it - * @param $name + * Decode a given name + * @param string|null $name + * + * @return string */ - public function setName($name) { - $decoder = $this->config['decoder']['attachment']; + public function decodeName(?string $name): string { if ($name !== null) { - if($decoder === 'utf-8' && extension_loaded('imap')) { - $this->name = \imap_utf8($name); - }else{ - $this->name = mb_decode_mimeheader($name); + if (str_contains($name, "''")) { + $parts = explode("''", $name); + if (EncodingAliases::has($parts[0])) { + $name = implode("''", array_slice($parts, 1)); + } + } + + $decoder = $this->config['decoder']['message']; + if (preg_match('/=\?([^?]+)\?(Q|B)\?(.+)\?=/i', $name, $matches)) { + $name = $this->part->getHeader()->decode($name); + } elseif ($decoder === 'utf-8' && extension_loaded('imap')) { + $name = \imap_utf8($name); + } + + // check if $name is url encoded + if (preg_match('/%[0-9A-F]{2}/i', $name)) { + $name = urldecode($name); } + + // sanitize $name + // order of '..' is important + return str_replace(['\\', '/', chr(0), ':', '..'], '', $name); } + return ""; } /** @@ -270,7 +316,7 @@ public function setName($name) { * * @return string|null */ - public function getMimeType(){ + public function getMimeType(): ?string { return (new \finfo())->buffer($this->getContent(), FILEINFO_MIME_TYPE); } @@ -279,21 +325,30 @@ public function getMimeType(){ * * @return string|null */ - public function getExtension(){ + public function getExtension(): ?string { + $extension = null; $guesser = "\Symfony\Component\Mime\MimeTypes"; if (class_exists($guesser) !== false) { /** @var Symfony\Component\Mime\MimeTypes $guesser */ $extensions = $guesser::getDefault()->getExtensions($this->getMimeType()); - return $extensions[0] ?? null; + $extension = $extensions[0] ?? null; } - - $deprecated_guesser = "\Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser"; - if (class_exists($deprecated_guesser) !== false){ - /** @var \Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser $deprecated_guesser */ - return $deprecated_guesser::getInstance()->guess($this->getMimeType()); + if ($extension === null) { + $deprecated_guesser = "\Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser"; + if (class_exists($deprecated_guesser) !== false) { + /** @var \Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser $deprecated_guesser */ + $extension = $deprecated_guesser::getInstance()->guess($this->getMimeType()); + } } - - return null; + if ($extension === null) { + $parts = explode(".", $this->filename); + $extension = count($parts) > 1 ? end($parts) : null; + } + if ($extension === null) { + $parts = explode(".", $this->name); + $extension = count($parts) > 1 ? end($parts) : null; + } + return $extension; } /** @@ -319,7 +374,7 @@ public function getMessage(): Message { * @return $this */ public function setMask($mask): Attachment { - if(class_exists($mask)){ + if (class_exists($mask)) { $this->mask = $mask; } @@ -342,12 +397,12 @@ public function getMask(): string { * @return mixed * @throws MaskNotFoundException */ - public function mask($mask = null){ + public function mask(string $mask = null): mixed { $mask = $mask !== null ? $mask : $this->mask; - if(class_exists($mask)){ + if (class_exists($mask)) { return new $mask($this); } - throw new MaskNotFoundException("Unknown mask provided: ".$mask); + throw new MaskNotFoundException("Unknown mask provided: " . $mask); } -} \ No newline at end of file +} diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Attribute.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Attribute.php index 627cc3153..c50cab757 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Attribute.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Attribute.php @@ -14,7 +14,6 @@ use ArrayAccess; use Carbon\Carbon; -use ReturnTypeWillChange; /** * Class Attribute @@ -24,25 +23,45 @@ class Attribute implements ArrayAccess { /** @var string $name */ - protected $name; + protected string $name; /** * Value holder * * @var array $values */ - protected $values = []; + protected array $values = []; /** * Attribute constructor. * @param string $name - * @param array|mixed $value + * @param mixed|null $value */ - public function __construct(string $name, $value = null) { + public function __construct(string $name, mixed $value = null) { $this->setName($name); $this->add($value); } + /** + * Handle class invocation calls + * + * @return array|string + */ + public function __invoke(): array|string { + if ($this->count() > 1) { + return $this->toArray(); + } + return $this->toString(); + } + + /** + * Return the serialized address + * + * @return array + */ + public function __serialize(){ + return $this->values; + } /** * Return the stringified attribute @@ -68,7 +87,7 @@ public function toString(): string { * @return array */ public function toArray(): array { - return $this->values; + return $this->__serialize(); } /** @@ -84,51 +103,72 @@ public function toDate(): Carbon { } /** - * Determine if a value exists at an offset. + * Determine if a value exists at a given key. + * + * @param int|string $key + * @return bool + */ + public function has(mixed $key = 0): bool { + return array_key_exists($key, $this->values); + } + + /** + * Determine if a value exists at a given key. + * + * @param int|string $key + * @return bool + */ + public function exist(mixed $key = 0): bool { + return $this->has($key); + } + + /** + * Check if the attribute contains the given value + * @param mixed $value * - * @param mixed $offset * @return bool */ - public function offsetExists($offset): bool { - return array_key_exists($offset, $this->values); + public function contains(mixed $value): bool { + return in_array($value, $this->values, true); } /** - * Get a value at a given offset. + * Get a value by a given key. * - * @param mixed $offset + * @param int|string $key * @return mixed */ - #[ReturnTypeWillChange] - public function offsetGet($offset) { - return $this->values[$offset]; + public function get(int|string $key = 0): mixed { + return $this->values[$key] ?? null; } /** - * Set the value at a given offset. + * Set the value by a given key. * - * @param mixed $offset - * @param mixed $value - * @return void + * @param mixed $key + * @param mixed $value + * @return Attribute */ - #[ReturnTypeWillChange] - public function offsetSet($offset, $value) { - if (is_null($offset)) { + public function set(mixed $value, mixed $key = 0): Attribute { + if (is_null($key)) { $this->values[] = $value; } else { - $this->values[$offset] = $value; + $this->values[$key] = $value; } + return $this; } /** - * Unset the value at a given offset. + * Unset a value by a given key. * - * @param string $offset - * @return void + * @param int|string $key + * @return Attribute */ - #[ReturnTypeWillChange] - public function offsetUnset($offset) { - unset($this->values[$offset]); + public function remove(int|string $key = 0): Attribute { + if (isset($this->values[$key])) { + unset($this->values[$key]); + } + return $this; } /** @@ -138,7 +178,7 @@ public function offsetUnset($offset) { * * @return Attribute */ - public function add($value, bool $strict = false): Attribute { + public function add(mixed $value, bool $strict = false): Attribute { if (is_array($value)) { return $this->merge($value, $strict); }elseif ($value !== null) { @@ -163,22 +203,13 @@ public function merge(array $values, bool $strict = false): Attribute { return $this; } - /** - * Check if the attribute contains the given value - * @param mixed $value - * - * @return bool - */ - public function contains($value): bool { - return in_array($value, $this->values, true); - } - /** * Attach a given value to the current value array * @param $value * @param bool $strict + * @return Attribute */ - public function attach($value, bool $strict = false) { + public function attach($value, bool $strict = false): Attribute { if ($strict === true) { if ($this->contains($value) === false) { $this->values[] = $value; @@ -186,6 +217,7 @@ public function attach($value, bool $strict = false) { }else{ $this->values[] = $value; } + return $this; } /** @@ -214,17 +246,9 @@ public function getName(): string { * * @return array */ - public function get(): array { - return $this->values; - } - - /** - * Alias method for self::get() - * - * @return array - */ public function all(): array { - return $this->get(); + reset($this->values); + return $this->values; } /** @@ -232,11 +256,8 @@ public function all(): array { * * @return mixed|null */ - public function first(){ - if ($this->offsetExists(0)) { - return $this->values[0]; - } - return null; + public function first(): mixed { + return reset($this->values); } /** @@ -244,11 +265,8 @@ public function first(){ * * @return mixed|null */ - public function last(){ - if (($cnt = $this->count()) > 0) { - return $this->values[$cnt - 1]; - } - return null; + public function last(): mixed { + return end($this->values); } /** @@ -259,4 +277,49 @@ public function last(){ public function count(): int { return count($this->values); } + + /** + * @see ArrayAccess::offsetExists + * @param mixed $offset + * @return bool + */ + public function offsetExists(mixed $offset): bool { + return $this->has($offset); + } + + /** + * @see ArrayAccess::offsetGet + * @param mixed $offset + * @return mixed + */ + public function offsetGet(mixed $offset): mixed { + return $this->get($offset); + } + + /** + * @see ArrayAccess::offsetSet + * @param mixed $offset + * @param mixed $value + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void { + $this->set($value, $offset); + } + + /** + * @see ArrayAccess::offsetUnset + * @param mixed $offset + * @return void + */ + public function offsetUnset(mixed $offset): void { + $this->remove($offset); + } + + /** + * @param callable $callback + * @return array + */ + public function map(callable $callback): array { + return array_map($callback, $this->values); + } } \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Client.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Client.php index 5af564238..8027dc53f 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Client.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Client.php @@ -15,13 +15,17 @@ use ErrorException; use Webklex\PHPIMAP\Connection\Protocols\ImapProtocol; use Webklex\PHPIMAP\Connection\Protocols\LegacyProtocol; -use Webklex\PHPIMAP\Connection\Protocols\Protocol; use Webklex\PHPIMAP\Connection\Protocols\ProtocolInterface; use Webklex\PHPIMAP\Exceptions\AuthFailedException; use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; +use Webklex\PHPIMAP\Exceptions\EventNotFoundException; use Webklex\PHPIMAP\Exceptions\FolderFetchingException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; use Webklex\PHPIMAP\Exceptions\MaskNotFoundException; use Webklex\PHPIMAP\Exceptions\ProtocolNotSupportedException; +use Webklex\PHPIMAP\Exceptions\ResponseException; +use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\Support\FolderCollection; use Webklex\PHPIMAP\Support\Masks\AttachmentMask; use Webklex\PHPIMAP\Support\Masks\MessageMask; @@ -38,30 +42,30 @@ class Client { /** * Connection resource * - * @var boolean|Protocol|ProtocolInterface + * @var ?ProtocolInterface */ - public $connection = false; + public ?ProtocolInterface $connection = null; /** * Server hostname. * * @var string */ - public $host; + public string $host; /** * Server port. * * @var int */ - public $port; + public int $port; /** * Service protocol. * - * @var int + * @var string */ - public $protocol; + public string $protocol; /** * Server encryption. @@ -69,20 +73,20 @@ class Client { * * @var string */ - public $encryption; + public string $encryption; /** * If server has to validate cert. * * @var bool */ - public $validate_cert = true; + public bool $validate_cert = true; /** * Proxy settings * @var array */ - protected $proxy = [ + protected array $proxy = [ 'socket' => null, 'request_fulluri' => false, 'username' => null, @@ -93,63 +97,63 @@ class Client { * Connection timeout * @var int $timeout */ - public $timeout; + public int $timeout; /** - * Account username/ + * Account username * - * @var mixed + * @var string */ - public $username; + public string $username; /** * Account password. * * @var string */ - public $password; + public string $password; /** * Additional data fetched from the server. * - * @var string + * @var array */ - public $extensions; + public array $extensions; /** * Account authentication method. * - * @var string + * @var ?string */ - public $authentication; + public ?string $authentication; /** * Active folder path. * - * @var string + * @var ?string */ - protected $active_folder = null; + protected ?string $active_folder = null; /** * Default message mask * * @var string $default_message_mask */ - protected $default_message_mask = MessageMask::class; + protected string $default_message_mask = MessageMask::class; /** * Default attachment mask * * @var string $default_attachment_mask */ - protected $default_attachment_mask = AttachmentMask::class; + protected string $default_attachment_mask = AttachmentMask::class; /** * Used default account values * * @var array $default_account_config */ - protected $default_account_config = [ + protected array $default_account_config = [ 'host' => 'localhost', 'port' => 993, 'protocol' => 'imap', @@ -182,11 +186,35 @@ public function __construct(array $config = []) { /** * Client destructor + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException */ public function __destruct() { $this->disconnect(); } + /** + * Clone the current Client instance + * + * @return Client + */ + public function clone(): Client { + $client = new self(); + $client->events = $this->events; + $client->timeout = $this->timeout; + $client->active_folder = $this->active_folder; + $client->default_account_config = $this->default_account_config; + $config = $this->getAccountConfig(); + foreach($config as $key => $value) { + $client->setAccountConfig($key, $config, $this->default_account_config); + } + $client->default_message_mask = $this->default_message_mask; + $client->default_attachment_mask = $this->default_message_mask; + return $client; + } + /** * Set the Client configuration * @param array $config @@ -204,13 +232,26 @@ public function setConfig(array $config): Client { return $this; } + /** + * Get the current config + * + * @return array + */ + public function getConfig(): array { + $config = []; + foreach($this->default_account_config as $key => $value) { + $config[$key] = $this->$key; + } + return $config; + } + /** * Set a specific account config * @param string $key * @param array $config * @param array $default_config */ - private function setAccountConfig(string $key, array $config, array $default_config){ + private function setAccountConfig(string $key, array $config, array $default_config): void { $value = $this->default_account_config[$key]; if(isset($config[$key])) { $value = $config[$key]; @@ -220,11 +261,26 @@ private function setAccountConfig(string $key, array $config, array $default_con $this->$key = $value; } + /** + * Get the current account config + * + * @return array + */ + public function getAccountConfig(): array { + $config = []; + foreach($this->default_account_config as $key => $value) { + if(property_exists($this, $key)) { + $config[$key] = $this->$key; + } + } + return $config; + } + /** * Look for a possible events in any available config * @param $config */ - protected function setEventsFromConfig($config) { + protected function setEventsFromConfig($config): void { $this->events = ClientManager::get("events"); if(isset($config['events'])){ foreach($config['events'] as $section => $events) { @@ -239,8 +295,7 @@ protected function setEventsFromConfig($config) { * * @throws MaskNotFoundException */ - protected function setMaskFromConfig($config) { - $default_config = ClientManager::get("masks"); + protected function setMaskFromConfig($config): void { if(isset($config['masks'])){ if(isset($config['masks']['message'])) { @@ -250,48 +305,56 @@ protected function setMaskFromConfig($config) { throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['message']); } }else{ - if(class_exists($default_config['message'])) { - $this->default_message_mask = $default_config['message']; + $default_mask = ClientManager::getMask("message"); + if($default_mask != ""){ + $this->default_message_mask = $default_mask; }else{ - throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']); + throw new MaskNotFoundException("Unknown message mask provided"); } } if(isset($config['masks']['attachment'])) { if(class_exists($config['masks']['attachment'])) { $this->default_attachment_mask = $config['masks']['attachment']; }else{ - throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['attachment']); + throw new MaskNotFoundException("Unknown mask provided: ". $config['masks']['attachment']); } }else{ - if(class_exists($default_config['attachment'])) { - $this->default_attachment_mask = $default_config['attachment']; + $default_mask = ClientManager::getMask("attachment"); + if($default_mask != ""){ + $this->default_attachment_mask = $default_mask; }else{ - throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']); + throw new MaskNotFoundException("Unknown attachment mask provided"); } } }else{ - if(class_exists($default_config['message'])) { - $this->default_message_mask = $default_config['message']; + $default_mask = ClientManager::getMask("message"); + if($default_mask != ""){ + $this->default_message_mask = $default_mask; }else{ - throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']); + throw new MaskNotFoundException("Unknown message mask provided"); } - if(class_exists($default_config['attachment'])) { - $this->default_attachment_mask = $default_config['attachment']; + $default_mask = ClientManager::getMask("attachment"); + if($default_mask != ""){ + $this->default_attachment_mask = $default_mask; }else{ - throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']); + throw new MaskNotFoundException("Unknown attachment mask provided"); } } - } /** * Get the current imap resource * - * @return bool|Protocol|ProtocolInterface + * @return ProtocolInterface * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function getConnection() { + public function getConnection(): ProtocolInterface { $this->checkConnection(); return $this->connection; } @@ -307,21 +370,38 @@ public function isConnected(): bool { /** * Determine if connection was established and connect if not. + * Returns true if the connection was closed and has been reopened. * * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function checkConnection() { - if (!$this->isConnected()) { + public function checkConnection(): bool { + try { + if (!$this->isConnected()) { + $this->connect(); + return true; + } + } catch (\Throwable) { $this->connect(); } + return false; } /** * Force the connection to reconnect * * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function reconnect() { + public function reconnect(): void { if ($this->isConnected()) { $this->disconnect(); } @@ -333,6 +413,11 @@ public function reconnect() { * * @return $this * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function connect(): Client { $this->disconnect(); @@ -347,7 +432,7 @@ public function connect(): Client { throw new ConnectionFailedException("connection setup failed", 0, new ProtocolNotSupportedException($protocol." is an unsupported protocol")); } $this->connection = new LegacyProtocol($this->validate_cert, $this->encryption); - if (strpos($protocol, "legacy-") === 0) { + if (str_starts_with($protocol, "legacy-")) { $protocol = substr($protocol, 7); } $this->connection->setProtocol($protocol); @@ -363,9 +448,7 @@ public function connect(): Client { try { $this->connection->connect($this->host, $this->port); - } catch (ErrorException $e) { - throw new ConnectionFailedException("connection setup failed", 0, $e); - } catch (Exceptions\RuntimeException $e) { + } catch (ErrorException|RuntimeException $e) { throw new ConnectionFailedException("connection setup failed", 0, $e); } $this->authenticate(); @@ -376,19 +459,18 @@ public function connect(): Client { /** * Authenticate the current session * - * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException */ - protected function authenticate() { - try { - if ($this->authentication == "oauth") { - if (!$this->connection->authenticate($this->username, $this->password)) { - throw new AuthFailedException(); - } - } elseif (!$this->connection->login($this->username, $this->password)) { + protected function authenticate(): void { + if ($this->authentication == "oauth") { + if (!$this->connection->authenticate($this->username, $this->password)->validatedData()) { throw new AuthFailedException(); } - } catch (AuthFailedException $e) { - throw new ConnectionFailedException("connection setup failed", 0, $e); + } elseif (!$this->connection->login($this->username, $this->password)->validatedData()) { + throw new AuthFailedException(); } } @@ -396,9 +478,12 @@ protected function authenticate() { * Disconnect from server. * * @return $this + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException */ public function disconnect(): Client { - if ($this->isConnected() && $this->connection !== false) { + if ($this->isConnected()) { $this->connection->logout(); } $this->active_folder = null; @@ -409,22 +494,23 @@ public function disconnect(): Client { /** * Get a folder instance by a folder name * @param string $folder_name - * @param string|bool|null $delimiter - * + * @param string|null $delimiter + * @param bool $utf7 * @return Folder|null + * @throws AuthFailedException * @throws ConnectionFailedException * @throws FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException */ - public function getFolder(string $folder_name, $delimiter = null) { - if ($delimiter !== false && $delimiter !== null) { - return $this->getFolderByPath($folder_name); - } - + public function getFolder(string $folder_name, ?string $delimiter = null, bool $utf7 = false): ?Folder { // Set delimiter to false to force selection via getFolderByName (maybe useful for uncommon folder names) $delimiter = is_null($delimiter) ? ClientManager::get('options.delimiter', "/") : $delimiter; - if (strpos($folder_name, (string)$delimiter) !== false) { - return $this->getFolderByPath($folder_name); + + if (str_contains($folder_name, (string)$delimiter)) { + return $this->getFolderByPath($folder_name, $utf7); } return $this->getFolderByName($folder_name); @@ -433,27 +519,39 @@ public function getFolder(string $folder_name, $delimiter = null) { /** * Get a folder instance by a folder name * @param $folder_name + * @param bool $soft_fail If true, it will return null instead of throwing an exception * * @return Folder|null - * @throws ConnectionFailedException * @throws FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function getFolderByName($folder_name) { - return $this->getFolders(false)->where("name", $folder_name)->first(); + public function getFolderByName($folder_name, bool $soft_fail = false): ?Folder { + return $this->getFolders(false, null, $soft_fail)->where("name", $folder_name)->first(); } /** * Get a folder instance by a folder path * @param $folder_path + * @param bool $utf7 + * @param bool $soft_fail If true, it will return null instead of throwing an exception * * @return Folder|null + * @throws AuthFailedException * @throws ConnectionFailedException * @throws FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException */ - public function getFolderByPath($folder_path) { - return $this->getFolders(false)->where("path", $folder_path)->first(); + public function getFolderByPath($folder_path, bool $utf7 = false, bool $soft_fail = false): ?Folder { + if (!$utf7) $folder_path = EncodingAliases::convert($folder_path, "utf-8", "utf7-imap"); + return $this->getFolders(false, null, $soft_fail)->where("path", $folder_path)->first(); } /** @@ -462,27 +560,32 @@ public function getFolderByPath($folder_path) { * * @param boolean $hierarchical * @param string|null $parent_folder + * @param bool $soft_fail If true, it will return an empty collection instead of throwing an exception * * @return FolderCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException */ - public function getFolders(bool $hierarchical = true, string $parent_folder = null): FolderCollection { + public function getFolders(bool $hierarchical = true, string $parent_folder = null, bool $soft_fail = false): FolderCollection { $this->checkConnection(); $folders = FolderCollection::make([]); $pattern = $parent_folder.($hierarchical ? '%' : '*'); - $items = $this->connection->folders('', $pattern); + $items = $this->connection->folders('', $pattern)->validatedData(); - if(is_array($items)){ + if(!empty($items)){ foreach ($items as $folder_name => $item) { $folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]); if ($hierarchical && $folder->hasChildren()) { $pattern = $folder->full_name.$folder->delimiter.'%'; - $children = $this->getFolders(true, $pattern); + $children = $this->getFolders(true, $pattern, $soft_fail); $folder->setChildren($children); } @@ -490,9 +593,11 @@ public function getFolders(bool $hierarchical = true, string $parent_folder = nu } return $folders; - }else{ + }else if (!$soft_fail){ throw new FolderFetchingException("failed to fetch any folders"); } + + return $folders; } /** @@ -501,27 +606,32 @@ public function getFolders(bool $hierarchical = true, string $parent_folder = nu * * @param boolean $hierarchical * @param string|null $parent_folder + * @param bool $soft_fail If true, it will return an empty collection instead of throwing an exception * * @return FolderCollection - * @throws ConnectionFailedException * @throws FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function getFoldersWithStatus(bool $hierarchical = true, string $parent_folder = null): FolderCollection { + public function getFoldersWithStatus(bool $hierarchical = true, string $parent_folder = null, bool $soft_fail = false): FolderCollection { $this->checkConnection(); $folders = FolderCollection::make([]); $pattern = $parent_folder.($hierarchical ? '%' : '*'); - $items = $this->connection->folders('', $pattern); + $items = $this->connection->folders('', $pattern)->validatedData(); - if(is_array($items)){ + if(!empty($items)){ foreach ($items as $folder_name => $item) { $folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]); if ($hierarchical && $folder->hasChildren()) { $pattern = $folder->full_name.$folder->delimiter.'%'; - $children = $this->getFoldersWithStatus(true, $pattern); + $children = $this->getFoldersWithStatus(true, $pattern, $soft_fail); $folder->setChildren($children); } @@ -530,9 +640,11 @@ public function getFoldersWithStatus(bool $hierarchical = true, string $parent_f } return $folders; - }else{ + }else if (!$soft_fail){ throw new FolderFetchingException("failed to fetch any folders"); } + + return $folders; } /** @@ -540,37 +652,67 @@ public function getFoldersWithStatus(bool $hierarchical = true, string $parent_f * @param string $folder_path * @param boolean $force_select * - * @return array|bool + * @return array * @throws ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function openFolder(string $folder_path, bool $force_select = false) { + public function openFolder(string $folder_path, bool $force_select = false): array { if ($this->active_folder == $folder_path && $this->isConnected() && $force_select === false) { - return true; + return []; } $this->checkConnection(); $this->active_folder = $folder_path; - return $this->connection->selectFolder($folder_path); + return $this->connection->selectFolder($folder_path)->validatedData(); + } + + /** + * Set active folder + * @param string|null $folder_path + * + * @return void + */ + public function setActiveFolder(?string $folder_path = null): void { + $this->active_folder = $folder_path; + } + + /** + * Get active folder + * + * @return string|null + */ + public function getActiveFolder(): ?string { + return $this->active_folder; } /** * Create a new Folder - * @param string $folder + * @param string $folder_path * @param boolean $expunge - * + * @param bool $utf7 * @return Folder + * @throws AuthFailedException * @throws ConnectionFailedException + * @throws EventNotFoundException * @throws FolderFetchingException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException */ - public function createFolder(string $folder, bool $expunge = true): Folder { + public function createFolder(string $folder_path, bool $expunge = true, bool $utf7 = false): Folder { $this->checkConnection(); - $status = $this->connection->createFolder($folder); + + if (!$utf7) $folder_path = EncodingAliases::convert($folder_path, "utf-8", "UTF7-IMAP"); + + $status = $this->connection->createFolder($folder_path)->validatedData(); if($expunge) $this->expunge(); - $folder = $this->getFolderByPath($folder); + $folder = $this->getFolderByPath($folder_path, true); if($status && $folder) { $event = $this->getEvent("folder", "new"); $event::dispatch($folder); @@ -579,17 +721,52 @@ public function createFolder(string $folder, bool $expunge = true): Folder { return $folder; } + /** + * Delete a given folder + * @param string $folder_path + * @param boolean $expunge + * + * @return array + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException + */ + public function deleteFolder(string $folder_path, bool $expunge = true): array { + $this->checkConnection(); + + $folder = $this->getFolderByPath($folder_path); + if ($this->active_folder == $folder->path){ + $this->active_folder = null; + } + $status = $this->getConnection()->deleteFolder($folder->path)->validatedData(); + if ($expunge) $this->expunge(); + + $event = $this->getEvent("folder", "deleted"); + $event::dispatch($folder); + + return $status; + } + /** * Check a given folder - * @param $folder + * @param string $folder_path * - * @return array|bool + * @return array * @throws ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function checkFolder($folder) { + public function checkFolder(string $folder_path): array { $this->checkConnection(); - return $this->connection->examineFolder($folder); + return $this->connection->examineFolder($folder_path)->validatedData(); } /** @@ -597,7 +774,7 @@ public function checkFolder($folder) { * * @return string */ - public function getFolderPath(){ + public function getFolderPath(): string { return $this->active_folder; } @@ -606,14 +783,18 @@ public function getFolderPath(){ * Ref.: https://datatracker.ietf.org/doc/html/rfc2971 * * @param array|null $ids - * @return array|bool|void|null + * @return array * * @throws ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function Id(array $ids = null) { + public function Id(array $ids = null): array { $this->checkConnection(); - return $this->connection->ID($ids); + return $this->connection->ID($ids)->validatedData(); } /** @@ -621,11 +802,15 @@ public function Id(array $ids = null) { * * @return array * @throws ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function getQuota(): array { $this->checkConnection(); - return $this->connection->getQuota($this->username); + return $this->connection->getQuota($this->username)->validatedData(); } /** @@ -634,32 +819,46 @@ public function getQuota(): array { * * @return array * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function getQuotaRoot(string $quota_root = 'INBOX'): array { $this->checkConnection(); - return $this->connection->getQuotaRoot($quota_root); + return $this->connection->getQuotaRoot($quota_root)->validatedData(); } /** * Delete all messages marked for deletion * - * @return bool + * @return array * @throws ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function expunge(): bool { + public function expunge(): array { $this->checkConnection(); - return $this->connection->expunge(); + return $this->connection->expunge()->validatedData(); } /** * Set the connection timeout * @param integer $timeout * - * @return Protocol + * @return ProtocolInterface * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function setTimeout(int $timeout): Protocol { + public function setTimeout(int $timeout): ProtocolInterface { $this->timeout = $timeout; if ($this->isConnected()) { $this->connection->setConnectionTimeout($timeout); @@ -673,6 +872,11 @@ public function setTimeout(int $timeout): Protocol { * * @return int * @throws ConnectionFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function getTimeout(): int { $this->checkConnection(); diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/ClientManager.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/ClientManager.php index 61557ef29..7f724ffe0 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/ClientManager.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/ClientManager.php @@ -26,18 +26,18 @@ class ClientManager { * * @var array $config */ - public static $config = []; + public static array $config = []; /** * @var array $accounts */ - protected $accounts = []; + protected array $accounts = []; /** * ClientManager constructor. * @param array|string $config */ - public function __construct($config = []) { + public function __construct(array|string $config = []) { $this->setConfig($config); } @@ -69,24 +69,24 @@ public function make(array $config): Client { /** * Get a dotted config parameter * @param string $key - * @param null $default + * @param null $default * * @return mixed|null */ - public static function get(string $key, $default = null) { + public static function get(string $key, $default = null): mixed { $parts = explode('.', $key); $value = null; - foreach($parts as $part) { - if($value === null) { - if(isset(self::$config[$part])) { + foreach ($parts as $part) { + if ($value === null) { + if (isset(self::$config[$part])) { $value = self::$config[$part]; - }else{ + } else { break; } - }else{ - if(isset($value[$part])) { + } else { + if (isset($value[$part])) { $value = $value[$part]; - }else{ + } else { break; } } @@ -95,6 +95,22 @@ public static function get(string $key, $default = null) { return $value === null ? $default : $value; } + /** + * Get the mask for a given section + * @param string $section section name such as "message" or "attachment" + * + * @return string|null + */ + public static function getMask(string $section): ?string { + $default_masks = ClientManager::get("masks"); + if (isset($default_masks[$section])) { + if (class_exists($default_masks[$section])) { + return $default_masks[$section]; + } + } + return null; + } + /** * Resolve a account instance. * @param string|null $name @@ -134,12 +150,13 @@ protected function resolve(string $name): Client { * * @return array */ - protected function getClientConfig($name): array { - if ($name === null || $name === 'null') { + protected function getClientConfig(?string $name): array { + if ($name === null || $name === 'null' || $name === "") { return ['driver' => 'null']; } + $account = self::$config["accounts"][$name] ?? []; - return is_array(self::$config["accounts"][$name]) ? self::$config["accounts"][$name] : []; + return is_array($account) ? $account : []; } /** @@ -157,7 +174,7 @@ public function getDefaultAccount(): string { * * @return void */ - public function setDefaultAccount(string $name) { + public function setDefaultAccount(string $name): void { self::$config['default'] = $name; } @@ -173,29 +190,29 @@ public function setDefaultAccount(string $name) { * * @return $this */ - public function setConfig($config): ClientManager { + public function setConfig(array|string $config): ClientManager { - if(is_array($config) === false) { + if (is_array($config) === false) { $config = require $config; } $config_key = 'imap'; - $path = __DIR__.'/config/'.$config_key.'.php'; + $path = __DIR__ . '/config/' . $config_key . '.php'; $vendor_config = require $path; $config = $this->array_merge_recursive_distinct($vendor_config, $config); - if(is_array($config)){ - if(isset($config['default'])){ - if(isset($config['accounts']) && $config['default']){ + if (is_array($config)) { + if (isset($config['default'])) { + if (isset($config['accounts']) && $config['default']) { $default_config = $vendor_config['accounts']['default']; - if(isset($config['accounts'][$config['default']])){ + if (isset($config['accounts'][$config['default']])) { $default_config = array_merge($default_config, $config['accounts'][$config['default']]); } - if(is_array($config['accounts'])){ - foreach($config['accounts'] as $account_key => $account){ + if (is_array($config['accounts'])) { + foreach ($config['accounts'] as $account_key => $account) { $config['accounts'][$account_key] = array_merge($default_config, $account); } } @@ -223,7 +240,7 @@ public function setConfig($config): ClientManager { * @link http://www.php.net/manual/en/function.array-merge-recursive.php#96201 * @author Mark Roduner */ - private function array_merge_recursive_distinct() { + private function array_merge_recursive_distinct(): mixed { $arrays = func_get_args(); $base = array_shift($arrays); @@ -234,20 +251,20 @@ private function array_merge_recursive_distinct() { return array_keys($arr) !== range(0, count($arr) - 1); }; - if(!is_array($base)) $base = empty($base) ? array() : array($base); + if (!is_array($base)) $base = empty($base) ? array() : array($base); - foreach($arrays as $append) { + foreach ($arrays as $append) { - if(!is_array($append)) $append = array($append); + if (!is_array($append)) $append = array($append); - foreach($append as $key => $value) { + foreach ($append as $key => $value) { - if(!array_key_exists($key, $base) and !is_numeric($key)) { + if (!array_key_exists($key, $base) and !is_numeric($key)) { $base[$key] = $value; continue; } - if( + if ( ( is_array($value) && $isAssoc($value) @@ -261,8 +278,8 @@ private function array_merge_recursive_distinct() { // else merging $baseConfig['dispositions'] = ['attachment', 'inline'] with $customConfig['dispositions'] = ['attachment'] // results in $resultConfig['dispositions'] = ['attachment', 'inline'] $base[$key] = $this->array_merge_recursive_distinct($base[$key], $value); - } else if(is_numeric($key)) { - if(!in_array($value, $base)) $base[] = $value; + } else if (is_numeric($key)) { + if (!in_array($value, $base)) $base[] = $value; } else { $base[$key] = $value; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php index b910c6227..4d54579f8 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php @@ -15,8 +15,11 @@ use Exception; use Webklex\PHPIMAP\Exceptions\AuthFailedException; use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException; use Webklex\PHPIMAP\Exceptions\MessageNotFoundException; +use Webklex\PHPIMAP\Exceptions\ResponseException; use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\Header; use Webklex\PHPIMAP\IMAP; @@ -25,6 +28,8 @@ * Class ImapProtocol * * @package Webklex\PHPIMAP\Connection\Protocols + * + * @reference https://www.rfc-editor.org/rfc/rfc2087.txt */ class ImapProtocol extends Protocol { @@ -32,20 +37,20 @@ class ImapProtocol extends Protocol { * Request noun * @var int */ - protected $noun = 0; + protected int $noun = 0; /** * Imap constructor. * @param bool $cert_validation set to false to skip SSL certificate validation * @param mixed $encryption Connection encryption method */ - public function __construct(bool $cert_validation = true, $encryption = false) { + public function __construct(bool $cert_validation = true, mixed $encryption = false) { $this->setCertValidation($cert_validation); $this->encryption = $encryption; } /** - * Public destructor + * Handle the class destruction / tear down */ public function __destruct() { $this->logout(); @@ -58,7 +63,7 @@ public function __destruct() { * * @throws ConnectionFailedException */ - public function connect(string $host, $port = null) { + public function connect(string $host, int $port = null): bool { $transport = 'tcp'; $encryption = ''; @@ -71,8 +76,9 @@ public function connect(string $host, $port = null) { } $port = $port === null ? 143 : $port; try { + $response = new Response(0, $this->debug); $this->stream = $this->createStream($transport, $host, $port, $this->connection_timeout); - if (!$this->assumedNextLine('* OK')) { + if (!$this->stream || !$this->assumedNextLine($response, '* OK')) { throw new ConnectionFailedException('connection refused'); } if ($encryption == 'starttls') { @@ -81,17 +87,20 @@ public function connect(string $host, $port = null) { } catch (Exception $e) { throw new ConnectionFailedException('connection failed', 0, $e); } + return true; } /** * Enable tls on the current connection * * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - protected function enableStartTls(){ + protected function enableStartTls() { $response = $this->requestAndResponse('STARTTLS'); - $result = $response && stream_socket_enable_crypto($this->stream, true, $this->getCryptoMethod()); + $result = $response->successful() && stream_socket_enable_crypto($this->stream, true, $this->getCryptoMethod()); if (!$result) { throw new ConnectionFailedException('failed to enable TLS'); } @@ -103,27 +112,30 @@ protected function enableStartTls(){ * @return string next line * @throws RuntimeException */ - public function nextLine(): string { + public function nextLine(Response $response): string { $line = ""; - while (($next_char = fread($this->stream, 1)) !== false && $next_char !== "\n") { + while (($next_char = fread($this->stream, 1)) !== false && !in_array($next_char, ["","\n"])) { $line .= $next_char; } - if ($line === "" && $next_char === false) { + if ($line === "" && ($next_char === false || $next_char === "")) { throw new RuntimeException('empty response'); } - if ($this->debug) echo "<< ".$line."\n"; - return $line . "\n"; + $line .= "\n"; + $response->addResponse($line); + if ($this->debug) echo "<< " . $line; + return $line; } /** * Get the next line and check if it starts with a given string + * @param Response $response * @param string $start * * @return bool * @throws RuntimeException */ - protected function assumedNextLine(string $start): bool { - return strpos($this->nextLine(), $start) === 0; + protected function assumedNextLine(Response $response, string $start): bool { + return str_starts_with($this->nextLine($response), $start); } /** @@ -133,34 +145,37 @@ protected function assumedNextLine(string $start): bool { * @return string next line * @throws RuntimeException */ - protected function nextTaggedLine(&$tag): string { - $line = $this->nextLine(); - list($tag, $line) = explode(' ', $line, 2); + protected function nextTaggedLine(Response $response, ?string &$tag): string { + $line = $this->nextLine($response); + if (str_contains($line, ' ')) { + list($tag, $line) = explode(' ', $line, 2); + } - return $line; + return $line ?? ''; } /** * Get the next line and check if it contains a given string and split the tag + * @param Response $response * @param string $start * @param $tag * * @return bool * @throws RuntimeException */ - protected function assumedNextTaggedLine(string $start, &$tag): bool { - $line = $this->nextTaggedLine($tag); - return strpos($line, $start) !== false; + protected function assumedNextTaggedLine(Response $response, string $start, &$tag): bool { + return str_contains($this->nextTaggedLine($response, $tag), $start); } /** * Split a given line in values. A value is literal of any form or a list + * @param Response $response * @param string $line * * @return array * @throws RuntimeException */ - protected function decodeLine(string $line): array { + protected function decodeLine(Response $response, string $line): array { $tokens = []; $stack = []; @@ -178,7 +193,7 @@ protected function decodeLine(string $line): array { $token = substr($token, 1); } if ($token[0] == '"') { - if (preg_match('%^\(*"((.|\\\\|\\")*?)" *%', $line, $matches)) { + if (preg_match('%^\(*\"((.|\\\|\")*?)\"( |$)%', $line, $matches)) { $tokens[] = $matches[1]; $line = substr($line, strlen($matches[0])); continue; @@ -190,14 +205,14 @@ protected function decodeLine(string $line): array { if (is_numeric($chars)) { $token = ''; while (strlen($token) < $chars) { - $token .= $this->nextLine(); + $token .= $this->nextLine($response); } $line = ''; if (strlen($token) > $chars) { $line = substr($token, $chars); $token = substr($token, 0, $chars); } else { - $line .= $this->nextLine(); + $line .= $this->nextLine($response); } $tokens[] = $token; $line = trim($line) . ' '; @@ -216,7 +231,7 @@ protected function decodeLine(string $line): array { } $token = $tokens; $tokens = array_pop($stack); - // special handline if more than one closing brace + // special handling if more than one closing brace while ($braces-- > 0) { $tokens[] = $token; $token = $tokens; @@ -239,6 +254,7 @@ protected function decodeLine(string $line): array { /** * Read abd decode a response "line" + * @param Response $response * @param array|string $tokens to decode * @param string $wantedTag targeted tag * @param bool $dontParse if true only the unparsed line is returned in $tokens @@ -246,10 +262,10 @@ protected function decodeLine(string $line): array { * @return bool * @throws RuntimeException */ - public function readLine(&$tokens = [], string $wantedTag = '*', bool $dontParse = false): bool { - $line = $this->nextTaggedLine($tag); // get next tag + public function readLine(Response $response, array|string &$tokens = [], string $wantedTag = '*', bool $dontParse = false): bool { + $line = $this->nextTaggedLine($response, $tag); // get next tag if (!$dontParse) { - $tokens = $this->decodeLine($line); + $tokens = $this->decodeLine($response, $line); } else { $tokens = $line; } @@ -260,33 +276,40 @@ public function readLine(&$tokens = [], string $wantedTag = '*', bool $dontParse /** * Read all lines of response until given tag is found + * @param Response $response * @param string $tag request tag * @param bool $dontParse if true every line is returned unparsed instead of the decoded tokens * - * @return array|bool|null tokens if success, false if error, null if bad request + * @return array + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function readResponse(string $tag, bool $dontParse = false) { + public function readResponse(Response $response, string $tag, bool $dontParse = false): array { $lines = []; - $tokens = null; // define $tokens variable before first use + $tokens = ""; // define $tokens variable before first use do { - $readAll = $this->readLine($tokens, $tag, $dontParse); + $readAll = $this->readLine($response, $tokens, $tag, $dontParse); $lines[] = $tokens; } while (!$readAll); + $original = $tokens; if ($dontParse) { // First two chars are still needed for the response code - $tokens = [substr($tokens, 0, 2)]; + $tokens = [trim(substr($tokens, 0, 3))]; } + $original = is_array($original)?$original : [$original]; + // last line has response code if ($tokens[0] == 'OK') { - return $lines ? $lines : true; - } elseif ($tokens[0] == 'NO') { - return false; + return $lines ?: [true]; + } elseif ($tokens[0] == 'NO' || $tokens[0] == 'BAD' || $tokens[0] == 'BYE') { + throw new ImapServerErrorException(implode("\n", $original)); } - return null; + throw new ImapBadRequestException(implode("\n", $original)); } /** @@ -295,9 +318,10 @@ public function readResponse(string $tag, bool $dontParse = false) { * @param array $tokens additional parameters to command, use escapeString() to prepare * @param string|null $tag provide a tag otherwise an autogenerated is returned * + * @return Response * @throws RuntimeException */ - public function sendRequest(string $command, array $tokens = [], string &$tag = null) { + public function sendRequest(string $command, array $tokens = [], string &$tag = null): Response { if (!$tag) { $this->noun++; $tag = 'TAG' . $this->noun; @@ -305,10 +329,12 @@ public function sendRequest(string $command, array $tokens = [], string &$tag = $line = $tag . ' ' . $command; + $response = new Response($this->noun, $this->debug); + foreach ($tokens as $token) { if (is_array($token)) { - $this->write($line . ' ' . $token[0]); - if (!$this->assumedNextLine('+ ')) { + $this->write($response, $line . ' ' . $token[0]); + if (!$this->assumedNextLine($response, '+ ')) { throw new RuntimeException('failed to send literal string'); } $line = $token[1]; @@ -316,48 +342,59 @@ public function sendRequest(string $command, array $tokens = [], string &$tag = $line .= ' ' . $token; } } - $this->write($line); + $this->write($response, $line); + + return $response; } /** * Write data to the current stream + * @param Response $response * @param string $data + * * @return void * @throws RuntimeException */ - public function write(string $data) { - if ($this->debug) echo ">> ".$data ."\n"; + public function write(Response $response, string $data): void { + $command = $data . "\r\n"; + if ($this->debug) echo ">> " . $command . "\n"; + + $response->addCommand($command); - if (fwrite($this->stream, $data . "\r\n") === false) { + if (fwrite($this->stream, $command) === false) { throw new RuntimeException('failed to write - connection closed?'); } } /** * Send a request and get response at once + * * @param string $command * @param array $tokens parameters as in sendRequest() * @param bool $dontParse if true unparsed lines are returned instead of tokens * - * @return array|bool|null response as in readResponse() + * @return Response response as in readResponse() + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function requestAndResponse(string $command, array $tokens = [], bool $dontParse = false) { - $this->sendRequest($command, $tokens, $tag); + public function requestAndResponse(string $command, array $tokens = [], bool $dontParse = false): Response { + $response = $this->sendRequest($command, $tokens, $tag); + $response->setResult($this->readResponse($response, $tag, $dontParse)); - return $this->readResponse($tag, $dontParse); + return $response; } /** * Escape one or more literals i.e. for sendRequest - * @param string|array $string the literal/-s + * @param array|string $string the literal/-s * * @return string|array escape literals, literals with newline ar returned * as array('{size}', 'string'); */ - public function escapeString($string) { + public function escapeString(array|string $string): array|string { if (func_num_args() < 2) { - if (strpos($string, "\n") !== false) { + if (str_contains($string, "\n")) { return ['{' . strlen($string) . '}', $string]; } else { return '"' . str_replace(['\\', '"'], ['\\\\', '\\"'], $string) . '"'; @@ -390,16 +427,21 @@ public function escapeList(array $list): string { /** * Login to a new session. + * * @param string $user username * @param string $password password * - * @return bool|mixed + * @return Response * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException */ - public function login(string $user, string $password): bool { + public function login(string $user, string $password): Response { try { - $response = $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true); - return $response !== null && $response !== false; + $command = 'LOGIN'; + $params = $this->escapeString($user, $password); + + return $this->requestAndResponse($command, $params, true); } catch (RuntimeException $e) { throw new AuthFailedException("failed to authenticate", 0, $e); } @@ -410,29 +452,29 @@ public function login(string $user, string $password): bool { * @param string $user username * @param string $token access token * - * @return bool + * @return Response * @throws AuthFailedException */ - public function authenticate(string $user, string $token): bool { + public function authenticate(string $user, string $token): Response { try { $authenticateParams = ['XOAUTH2', base64_encode("user=$user\1auth=Bearer $token\1\1")]; - $this->sendRequest('AUTHENTICATE', $authenticateParams); + $response = $this->sendRequest('AUTHENTICATE', $authenticateParams); while (true) { - $response = ""; - $is_plus = $this->readLine($response, '+', true); + $tokens = ""; + $is_plus = $this->readLine($response, $tokens, '+', true); if ($is_plus) { // try to log the challenge somewhere where it can be found - error_log("got an extra server challenge: $response"); + error_log("got an extra server challenge: $tokens"); // respond with an empty response. - $this->sendRequest(''); + $response->stack($this->sendRequest('')); } else { - if (preg_match('/^NO /i', $response) || - preg_match('/^BAD /i', $response)) { - error_log("got failure response: $response"); - return false; - } else if (preg_match("/^OK /i", $response)) { - return true; + if (preg_match('/^NO /i', $tokens) || + preg_match('/^BAD /i', $tokens)) { + error_log("got failure response: $tokens"); + return $response->addError("got failure response: $tokens"); + } else if (preg_match("/^OK /i", $tokens)) { + return $response->setResult(is_array($tokens) ? $tokens : [$tokens]); } } } @@ -444,47 +486,54 @@ public function authenticate(string $user, string $token): bool { /** * Logout of imap server * - * @return bool success + * @return Response */ - public function logout(): bool { - $result = false; - if ($this->stream) { - try { - $result = $this->requestAndResponse('LOGOUT', [], true); - } catch (Exception $e) {} - fclose($this->stream); - $this->stream = null; - $this->uid_cache = null; + public function logout(): Response { + if (!$this->stream) { + $this->reset(); + return new Response(0, $this->debug); + }elseif ($this->meta()["timed_out"]) { + $this->reset(); + return new Response(0, $this->debug); } - return $result !== false; + $result = null; + try { + $result = $this->requestAndResponse('LOGOUT', [], true); + fclose($this->stream); + } catch (\Throwable) {} + + $this->reset(); + + return $result ?? new Response(0, $this->debug); } /** - * Check if the current session is connected + * Reset the current stream and uid cache * - * @return bool + * @return void */ - public function connected(): bool { - return (boolean) $this->stream; + public function reset(): void { + $this->stream = null; + $this->uid_cache = []; } /** * Get an array of available capabilities * - * @return array list of capabilities + * @return Response list of capabilities + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException + * @throws ResponseException */ - public function getCapabilities(): array { + public function getCapabilities(): Response { $response = $this->requestAndResponse('CAPABILITY'); - if (!$response) return []; + if (!$response->getResponse()) return $response; - $capabilities = []; - foreach ($response as $line) { - $capabilities = array_merge($capabilities, $line); - } - return $capabilities; + return $response->setResult($response->validatedData()[0]); } /** @@ -492,15 +541,15 @@ public function getCapabilities(): array { * @param string $command can be 'EXAMINE' or 'SELECT' * @param string $folder target folder * - * @return bool|array + * @return Response * @throws RuntimeException */ - public function examineOrSelect(string $command = 'EXAMINE', string $folder = 'INBOX') { - $this->sendRequest($command, [$this->escapeString($folder)], $tag); + public function examineOrSelect(string $command = 'EXAMINE', string $folder = 'INBOX'): Response { + $response = $this->sendRequest($command, [$this->escapeString($folder)], $tag); $result = []; - $tokens = null; // define $tokens variable before first use - while (!$this->readLine($tokens, $tag)) { + $tokens = []; // define $tokens variable before first use + while (!$this->readLine($response, $tokens, $tag, false)) { if ($tokens[0] == 'FLAGS') { array_shift($tokens); $result['flags'] = $tokens; @@ -528,21 +577,23 @@ public function examineOrSelect(string $command = 'EXAMINE', string $folder = 'I } } + $response->setResult($result); + if ($tokens[0] != 'OK') { - return false; + $response->addError("request failed"); } - return $result; + return $response; } /** * Change the current folder * @param string $folder change to this folder * - * @return bool|array see examineOrselect() + * @return Response see examineOrSelect() * @throws RuntimeException */ - public function selectFolder(string $folder = 'INBOX') { - $this->uid_cache = null; + public function selectFolder(string $folder = 'INBOX'): Response { + $this->uid_cache = []; return $this->examineOrSelect('SELECT', $folder); } @@ -551,53 +602,56 @@ public function selectFolder(string $folder = 'INBOX') { * Examine a given folder * @param string $folder examine this folder * - * @return bool|array see examineOrselect() + * @return Response see examineOrSelect() * @throws RuntimeException */ - public function examineFolder(string $folder = 'INBOX') { + public function examineFolder(string $folder = 'INBOX'): Response { return $this->examineOrSelect('EXAMINE', $folder); } /** * Fetch one or more items of one or more messages - * @param string|array $items items to fetch [RFC822.HEADER, FLAGS, RFC822.TEXT, etc] - * @param int|array $from message for items or start message if $to !== null + * @param array|string $items items to fetch [RFC822.HEADER, FLAGS, RFC822.TEXT, etc] + * @param array|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 int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return string|array if only one item of one message is fetched it's returned as string + * @return Response 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 item of messages are fetched it's returned as (msgno => value) * if items of messages are fetched it's returned as (msgno => (name => value)) * @throws RuntimeException */ - public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { + public function fetch(array|string $items, array|int $from, mixed $to = null, int|string $uid = IMAP::ST_UID): Response { if (is_array($from)) { $set = implode(',', $from); } elseif ($to === null) { - $set = (int)$from; - } elseif ($to === INF) { - $set = (int)$from . ':*'; + $set = $from; + } elseif ($to == INF) { + $set = $from . ':*'; } else { - $set = (int)$from . ':' . (int)$to; + $set = $from . ':' . (int)$to; } $items = (array)$items; $itemList = $this->escapeList($items); - $this->sendRequest($this->buildUIDCommand("FETCH", $uid), [$set, $itemList], $tag); + $response = $this->sendRequest($this->buildUIDCommand("FETCH", $uid), [$set, $itemList], $tag); $result = []; - $tokens = null; // define $tokens variable before first use - while (!$this->readLine($tokens, $tag)) { + $tokens = []; // define $tokens variable before first use + while (!$this->readLine($response, $tokens, $tag)) { // ignore other responses if ($tokens[1] != 'FETCH') { continue; } + $uidKey = 0; + $data = []; + // find array key of UID value; try the last elements, or search for it - if ($uid) { + if ($uid === IMAP::ST_UID) { $count = count($tokens[2]); if ($tokens[2][$count - 2] == 'UID') { $uidKey = $count - 1; @@ -614,7 +668,7 @@ public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { } // ignore other messages - if ($to === null && !is_array($from) && ($uid ? $tokens[2][$uidKey] != $from : $tokens[0] != $from)) { + if ($to === null && !is_array($from) && ($uid === IMAP::ST_UID ? $tokens[2][$uidKey] != $from : $tokens[0] != $from)) { continue; } @@ -622,11 +676,11 @@ public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { if (count($items) == 1) { if ($tokens[2][0] == $items[0]) { $data = $tokens[2][1]; - } elseif ($uid && $tokens[2][2] == $items[0]) { + } elseif ($uid === IMAP::ST_UID && $tokens[2][2] == $items[0]) { $data = $tokens[2][3]; } else { $expectedResponse = 0; - // maybe the server send an other field we didn't wanted + // maybe the server send another 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) { @@ -642,7 +696,6 @@ public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { } } } else { - $data = []; while (key($tokens[2]) !== null) { $data[current($tokens[2])] = next($tokens[2]); next($tokens[2]); @@ -650,15 +703,14 @@ public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { } // 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)) { + if ($to === null && !is_array($from) && ($uid === IMAP::ST_UID ? $tokens[2][$uidKey] == $from : $tokens[0] == $from)) { // we still need to read all lines - while (!$this->readLine($tokens, $tag)) - - return $data; + if (!$this->readLine($response, $tokens, $tag)) + return $response->setResult($data); } - if ($uid) { + if ($uid === IMAP::ST_UID) { $result[$tokens[2][$uidKey]] = $data; - }else{ + } else { $result[$tokens[0]] = $data; } } @@ -667,75 +719,86 @@ public function fetch($items, $from, $to = null, $uid = IMAP::ST_UID) { throw new RuntimeException('the single id was not found in response'); } - return $result; + return $response->setResult($result); } /** * Fetch message headers - * @param array|int $uids + * @param int|array $uids * @param string $rfc * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException */ - public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array { - $result = $this->fetch(["$rfc.TEXT"], $uids, null, $uid); - return is_array($result) ? $result : []; + public function content(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response { + return $this->fetch(["$rfc.TEXT"], is_array($uids)?$uids:[$uids], null, $uid); } /** * Fetch message headers - * @param array|int $uids + * @param int|array $uids * @param string $rfc * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException */ - public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array{ - $result = $this->fetch(["$rfc.HEADER"], $uids, null, $uid); - return $result === "" ? [] : $result; + public function headers(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response { + return $this->fetch(["$rfc.HEADER"], is_array($uids)?$uids:[$uids], null, $uid); } /** * Fetch message flags - * @param array|int $uids + * @param int|array $uids * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response + * @throws RuntimeException + */ + public function flags(int|array $uids, int|string $uid = IMAP::ST_UID): Response { + return $this->fetch(["FLAGS"], is_array($uids)?$uids:[$uids], null, $uid); + } + + /** + * Fetch message sizes + * @param int|array $uids + * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use + * message numbers instead. + * + * @return Response * @throws RuntimeException */ - public function flags($uids, $uid = IMAP::ST_UID): array { - $result = $this->fetch(["FLAGS"], $uids, null, $uid); - return is_array($result) ? $result : []; + public function sizes(int|array $uids, int|string $uid = IMAP::ST_UID): Response { + return $this->fetch(["RFC822.SIZE"], is_array($uids)?$uids:[$uids], null, $uid); } /** * Get uid for a given id * @param int|null $id message number * - * @return array|string message number for given message or all messages as array + * @return Response message number for given message or all messages as array * @throws MessageNotFoundException */ - public function getUid($id = null) { - if (!$this->enable_uid_cache || $this->uid_cache === null || ($this->uid_cache && count($this->uid_cache) <= 0)) { + public function getUid(?int $id = null): Response { + if (!$this->enable_uid_cache || empty($this->uid_cache) || count($this->uid_cache) <= 0) { try { - $this->setUidCache($this->fetch('UID', 1, INF)); // set cache for this folder - } catch (RuntimeException $e) {} + $this->setUidCache((array)$this->fetch('UID', 1, INF)->data()); // set cache for this folder + } catch (RuntimeException) { + } } $uids = $this->uid_cache; if ($id == null) { - return $uids; + return Response::empty($this->debug)->setResult($uids); } foreach ($uids as $k => $v) { if ($k == $id) { - return $v; + return Response::empty($this->debug)->setResult($v); } } @@ -752,71 +815,80 @@ public function getUid($id = null) { * Get a message number for a uid * @param string $id uid * - * @return int message number + * @return Response message number * @throws MessageNotFoundException */ - public function getMessageNumber(string $id): int { - $ids = $this->getUid(); - foreach ($ids as $k => $v) { + public function getMessageNumber(string $id): Response { + foreach ($this->getUid()->data() as $k => $v) { if ($v == $id) { - return (int)$k; + return Response::empty($this->debug)->setResult((int)$k); } } - throw new MessageNotFoundException('message number not found'); + throw new MessageNotFoundException('message number not found: ' . $id); } /** * Get a list of available folders + * * @param string $reference mailbox reference for list * @param string $folder mailbox name match with wildcards * - * @return array folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..)) + * @return Response folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..)) + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function folders(string $reference = '', string $folder = '*'): array { - $result = []; - $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $folder)); - if (!$list || $list === true) { - return $result; - } + public function folders(string $reference = '', string $folder = '*'): Response { + $response = $this->requestAndResponse('LIST', $this->escapeString($reference, $folder))->setCanBeEmpty(true); + $list = $response->data(); - foreach ($list as $item) { - if (count($item) != 4 || $item[0] != 'LIST') { - continue; + $result = []; + if ($list[0] !== true) { + foreach ($list as $item) { + if (count($item) != 4 || $item[0] != 'LIST') { + continue; + } + $item[3] = str_replace("\\\\", "\\", str_replace("\\\"", "\"", $item[3])); + $result[$item[3]] = ['delimiter' => $item[2], 'flags' => $item[1]]; } - $result[$item[3]] = ['delimiter' => $item[2], 'flags' => $item[1]]; } - return $result; + return $response->setResult($result); } /** * Manage flags - * @param array $flags flags to set, add or remove - see $mode + * + * @param array|string $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 * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. - * @param null|string $item command used to store a flag + * message numbers instead. + * @param string|null $item command used to store a flag * - * @return bool|array new flags if $silent is false, else true or false depending on success + * @return Response new flags if $silent is false, else true or false depending on success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null) { - $flags = $this->escapeList($flags); + public function store( + array|string $flags, int $from, int $to = null, string $mode = null, bool $silent = true, int|string $uid = IMAP::ST_UID, string $item = null + ): Response { + $flags = $this->escapeList(is_array($flags) ? $flags : [$flags]); $set = $this->buildSet($from, $to); $command = $this->buildUIDCommand("STORE", $uid); - $item = ($mode == '-' ? "-" : "+").($item === null ? "FLAGS" : $item).($silent ? '.SILENT' : ""); + $item = ($mode == '-' ? "-" : "+") . ($item === null ? "FLAGS" : $item) . ($silent ? '.SILENT' : ""); $response = $this->requestAndResponse($command, [$set, $item, $flags], $silent); if ($silent) { - return (bool)$response; + return $response; } $result = []; @@ -827,20 +899,25 @@ public function store(array $flags, int $from, $to = null, $mode = null, bool $s $result[$token[0]] = $token[2][1]; } - return $result; + + return $response->setResult($result); } /** * Append a new message to given folder + * * @param string $folder name of target folder * @param string $message full message content * @param array|null $flags flags for new message - * @param string $date date for new message + * @param string|null $date date for new message * - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool { + public function appendMessage(string $folder, string $message, array $flags = null, string $date = null): Response { $tokens = []; $tokens[] = $this->escapeString($folder); if ($flags !== null) { @@ -851,25 +928,30 @@ public function appendMessage(string $folder, string $message, $flags = null, $d } $tokens[] = $this->escapeString($message); - return (bool) $this->requestAndResponse('APPEND', $tokens, true); + return $this->requestAndResponse('APPEND', $tokens, true); } /** - * Copy a message set from current folder to an other folder + * Copy a message set from current folder to another folder + * * @param string $folder destination folder * @param $from * @param int|null $to if null only one message ($from) is fetched, else it's the - * last message, INF means last message available + * last message, INF means last message available * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. + * message numbers instead. + * + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool { + public function copyMessage(string $folder, $from, int $to = null, int|string $uid = IMAP::ST_UID): Response { $set = $this->buildSet($from, $to); $command = $this->buildUIDCommand("COPY", $uid); - return (bool)$this->requestAndResponse($command, [$set, $this->escapeString($folder)], true); + + return $this->requestAndResponse($command, [$set, $this->escapeString($folder)], true); } /** @@ -878,12 +960,15 @@ public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_U * @param array $messages List of message identifiers * @param string $folder Destination folder * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. - * @return array|bool Tokens if operation successful, false if an error occurred + * message numbers instead. + * + * @return Response Tokens if operation successful, false if an error occurred * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) { + public function copyManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response { $command = $this->buildUIDCommand("COPY", $uid); $set = implode(',', $messages); @@ -893,37 +978,44 @@ public function copyManyMessages(array $messages, string $folder, $uid = IMAP::S } /** - * Move a message set from current folder to an other folder + * Move a message set from current folder to another folder + * * @param string $folder destination folder * @param $from * @param int|null $to if null only one message ($from) is fetched, else it's the * last message, INF means last message available * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. + * message numbers instead. + * + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool { + public function moveMessage(string $folder, $from, int $to = null, int|string $uid = IMAP::ST_UID): Response { $set = $this->buildSet($from, $to); $command = $this->buildUIDCommand("MOVE", $uid); - return (bool)$this->requestAndResponse($command, [$set, $this->escapeString($folder)], true); + return $this->requestAndResponse($command, [$set, $this->escapeString($folder)], true); } /** * Move multiple messages to the target folder + * * @param array $messages List of message identifiers * @param string $folder Destination folder * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. + * message numbers instead. + * + * @return Response * - * @return array|bool Tokens if operation successful, false if an error occurred + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) { + public function moveManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response { $command = $this->buildUIDCommand("MOVE", $uid); - $set = implode(',', $messages); $tokens = [$set, $this->escapeString($folder)]; @@ -934,19 +1026,21 @@ public function moveManyMessages(array $messages, string $folder, $uid = IMAP::S * Exchange identification information * Ref.: https://datatracker.ietf.org/doc/html/rfc2971 * - * @param null $ids - * @return array|bool|void|null + * @param array|null $ids + * @return Response * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function ID($ids = null) { + public function ID($ids = null): Response { $token = "NIL"; if (is_array($ids) && !empty($ids)) { $token = "("; foreach ($ids as $id) { - $token .= '"'.$id.'" '; + $token .= '"' . $id . '" '; } - $token = rtrim($token).")"; + $token = rtrim($token) . ")"; } return $this->requestAndResponse("ID", [$token], true); @@ -954,102 +1048,137 @@ public function ID($ids = null) { /** * Create a new folder (and parent folders if needed) + * * @param string $folder folder name + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function createFolder(string $folder): bool { - return (bool)$this->requestAndResponse('CREATE', [$this->escapeString($folder)], true); + public function createFolder(string $folder): Response { + 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 + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function renameFolder(string $old, string $new): bool { - return (bool)$this->requestAndResponse('RENAME', $this->escapeString($old, $new), true); + public function renameFolder(string $old, string $new): Response { + return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true); } /** * Delete a folder + * * @param string $folder folder name + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function deleteFolder(string $folder): bool { - return (bool)$this->requestAndResponse('DELETE', [$this->escapeString($folder)], true); + public function deleteFolder(string $folder): Response { + return $this->requestAndResponse('DELETE', [$this->escapeString($folder)], true); } /** * Subscribe to a folder + * * @param string $folder folder name + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function subscribeFolder(string $folder): bool { - return (bool)$this->requestAndResponse('SUBSCRIBE', [$this->escapeString($folder)], true); + public function subscribeFolder(string $folder): Response { + return $this->requestAndResponse('SUBSCRIBE', [$this->escapeString($folder)], true); } /** * Unsubscribe from a folder + * * @param string $folder folder name + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function unsubscribeFolder(string $folder): bool { - return (bool)$this->requestAndResponse('UNSUBSCRIBE', [$this->escapeString($folder)], true); + public function unsubscribeFolder(string $folder): Response { + return $this->requestAndResponse('UNSUBSCRIBE', [$this->escapeString($folder)], true); } /** * Apply session saved changes to the server * - * @return bool success + * @return Response + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function expunge(): bool { - return (bool)$this->requestAndResponse('EXPUNGE'); + public function expunge(): Response { + $this->uid_cache = []; + return $this->requestAndResponse('EXPUNGE'); } /** * Send noop command * - * @return bool success + * @return Response + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function noop(): bool { - return (bool)$this->requestAndResponse('NOOP'); + public function noop(): Response { + return $this->requestAndResponse('NOOP'); } /** * Retrieve the quota level settings, and usage statics per mailbox + * * @param $username + * @return Response * - * @return array + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException + * + * @Doc https://www.rfc-editor.org/rfc/rfc2087.txt */ - public function getQuota($username): array { - $result = $this->requestAndResponse("GETQUOTA", ['"#user/'.$username.'"']); - return is_array($result) ? $result : []; + public function getQuota($username): Response { + $command = "GETQUOTA"; + $params = ['"#user/' . $username . '"']; + + return $this->requestAndResponse($command, $params); } /** * Retrieve the quota settings per user + * * @param string $quota_root + * @return Response * - * @return array + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException + * + * @Doc https://www.rfc-editor.org/rfc/rfc2087.txt */ - public function getQuotaRoot(string $quota_root = 'INBOX'): array { - $result = $this->requestAndResponse("QUOTA", [$quota_root]); - return is_array($result) ? $result : []; + public function getQuotaRoot(string $quota_root = 'INBOX'): Response { + $command = "GETQUOTAROOT"; + $params = [$quota_root]; + + return $this->requestAndResponse($command, $params); } /** @@ -1058,8 +1187,8 @@ public function getQuotaRoot(string $quota_root = 'INBOX'): array { * @throws RuntimeException */ public function idle() { - $this->sendRequest("IDLE"); - if (!$this->assumedNextLine('+ ')) { + $response = $this->sendRequest("IDLE"); + if (!$this->assumedNextLine($response, '+ ')) { throw new RuntimeException('idle failed'); } } @@ -1069,8 +1198,9 @@ public function idle() { * @throws RuntimeException */ public function done(): bool { - $this->write("DONE"); - if (!$this->assumedNextTaggedLine('OK', $tags)) { + $response = new Response($this->noun, $this->debug); + $this->write($response, "DONE"); + if (!$this->assumedNextTaggedLine($response, 'OK', $tags)) { throw new RuntimeException('done failed'); } return true; @@ -1078,25 +1208,28 @@ public function done(): bool { /** * Search for matching messages + * * @param array $params * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use - * message numbers instead. + * message numbers instead. * - * @return array message ids + * @return Response message ids + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function search(array $params, $uid = IMAP::ST_UID): array { + public function search(array $params, int|string $uid = IMAP::ST_UID): Response { $command = $this->buildUIDCommand("SEARCH", $uid); - $response = $this->requestAndResponse($command, $params); - if (!$response) return []; + $response = $this->requestAndResponse($command, $params)->setCanBeEmpty(true); - foreach ($response as $ids) { - if ($ids[0] == 'SEARCH') { + foreach ($response->data() as $ids) { + if ($ids[0] === 'SEARCH') { array_shift($ids); - return $ids; + return $response->setResult($ids); } } - return []; + + return $response; } /** @@ -1105,41 +1238,48 @@ public function search(array $params, $uid = IMAP::ST_UID): array { * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException * @throws MessageNotFoundException * @throws InvalidMessageDateException */ - public function overview(string $sequence, $uid = IMAP::ST_UID): array { + public function overview(string $sequence, int|string $uid = IMAP::ST_UID): Response { $result = []; list($from, $to) = explode(":", $sequence); - $uids = $this->getUid(); + $response = $this->getUid(); $ids = []; - foreach ($uids as $msgn => $v) { - $id = $uid ? $v : $msgn; - if ( ($to >= $id && $from <= $id) || ($to === "*" && $from <= $id) ){ + foreach ($response->data() as $msgn => $v) { + $id = $uid === IMAP::ST_UID ? $v : $msgn; + if (($to >= $id && $from <= $id) || ($to === "*" && $from <= $id)) { $ids[] = $id; } } - $headers = $this->headers($ids, "RFC822", $uid); - foreach ($headers as $id => $raw_header) { - $result[$id] = (new Header($raw_header, false))->getAttributes(); + if (!empty($ids)) { + $headers = $this->headers($ids, "RFC822", $uid); + $response->stack($headers); + foreach ($headers->data() as $id => $raw_header) { + $result[$id] = (new Header($raw_header, false))->getAttributes(); + } } - return $result; + return $response->setResult($result)->setCanBeEmpty(true); } /** * Enable the debug mode + * + * @return void */ - public function enableDebug(){ + public function enableDebug(): void { $this->debug = true; } /** * Disable the debug mode + * + * @return void */ - public function disableDebug(){ + public function disableDebug(): void { $this->debug = false; } @@ -1150,7 +1290,7 @@ public function disableDebug(){ * * @return int|string */ - public function buildSet($from, $to = null) { + public function buildSet($from, $to = null): int|string { $set = (int)$from; if ($to !== null) { $set .= ':' . ($to == INF ? '*' : (int)$to); diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php index dd3d48981..10bc9d9f5 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php @@ -14,6 +14,7 @@ use Webklex\PHPIMAP\ClientManager; use Webklex\PHPIMAP\Exceptions\AuthFailedException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; use Webklex\PHPIMAP\Exceptions\MethodNotSupportedException; use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\IMAP; @@ -25,17 +26,16 @@ */ class LegacyProtocol extends Protocol { - protected $protocol = "imap"; - protected $host = null; - protected $port = null; - protected $encryption = null; + protected string $protocol = "imap"; + protected string $host = "localhost"; + protected int $port = 993; /** * Imap constructor. * @param bool $cert_validation set to false to skip SSL certificate validation * @param mixed $encryption Connection encryption method */ - public function __construct(bool $cert_validation = true, $encryption = false) { + public function __construct(bool $cert_validation = true, mixed $encryption = false) { $this->setCertValidation($cert_validation); $this->encryption = $encryption; } @@ -50,9 +50,9 @@ public function __destruct() { /** * Save the information for a nw connection * @param string $host - * @param null $port + * @param int|null $port */ - public function connect(string $host, $port = null) { + public function connect(string $host, int $port = null) { if ($this->encryption) { $encryption = strtolower($this->encryption); if ($encryption == "ssl") { @@ -69,42 +69,51 @@ public function connect(string $host, $port = null) { * @param string $user username * @param string $password password * - * @return bool - * @throws AuthFailedException - * @throws RuntimeException - */ - public function login(string $user, string $password): bool { - try { - $this->stream = \imap_open( - $this->getAddress(), - $user, - $password, - 0, - $attempts = 3, - ClientManager::get('options.open') - ); - } catch (\ErrorException $e) { - $errors = \imap_errors(); - $message = $e->getMessage().'. '.implode("; ", (is_array($errors) ? $errors : array())); - throw new AuthFailedException($message); - } + * @return Response + */ + public function login(string $user, string $password): Response { + return $this->response()->wrap(function($response) use ($user, $password) { + /** @var Response $response */ + try { + $this->stream = \imap_open( + $this->getAddress(), + $user, + $password, + 0, + $attempts = 3, + ClientManager::get('options.open') + ); + $response->addCommand("imap_open"); + } catch (\ErrorException $e) { + $errors = \imap_errors(); + $message = $e->getMessage() . '. ' . implode("; ", (is_array($errors) ? $errors : array())); + throw new AuthFailedException($message); + } + + if (!$this->stream) { + $errors = \imap_errors(); + $message = implode("; ", (is_array($errors) ? $errors : array())); + throw new AuthFailedException($message); + } - if(!$this->stream) { $errors = \imap_errors(); - $message = implode("; ", (is_array($errors) ? $errors : array())); - throw new AuthFailedException($message); - } + $response->addCommand("imap_errors"); + if (is_array($errors)) { + $status = $this->examineFolder(); + $response->stack($status); + if ($status->data()['exists'] !== 0) { + $message = implode("; ", $errors); + throw new RuntimeException($message); + } + } - $errors = \imap_errors(); - if(is_array($errors)) { - $status = $this->examineFolder(); - if($status['exists'] !== 0) { - $message = implode("; ", (is_array($errors) ? $errors : array())); - throw new RuntimeException($message); + if ($this->stream !== false) { + return ["TAG" . $response->Noun() . " OK [] Logged in\r\n"]; } - } - return $this->stream !== false; + $response->addError("failed to login"); + return []; + }); } /** @@ -112,10 +121,11 @@ public function login(string $user, string $password): bool { * @param string $user username * @param string $token access token * - * @return bool|resource - * @throws AuthFailedException|RuntimeException + * @return Response + * @throws AuthFailedException + * @throws RuntimeException */ - public function authenticate(string $user, string $token): bool { + public function authenticate(string $user, string $token): Response { return $this->login($user, $token); } @@ -125,12 +135,12 @@ public function authenticate(string $user, string $token): bool { * @return string */ protected function getAddress(): string { - $address = "{".$this->host.":".$this->port."/".$this->protocol; + $address = "{" . $this->host . ":" . $this->port . "/" . $this->protocol; if (!$this->cert_validation) { $address .= '/novalidate-cert'; } - if (in_array($this->encryption,['tls', 'notls', 'ssl'])) { - $address .= '/'.$this->encryption; + if (in_array($this->encryption, ['tls', 'notls', 'ssl'])) { + $address .= '/' . $this->encryption; } elseif ($this->encryption === "starttls") { $address .= '/tls'; } @@ -143,25 +153,25 @@ protected function getAddress(): string { /** * Logout of the current session * - * @return bool success - */ - public function logout(): bool { - if ($this->stream) { - $result = \imap_close($this->stream, IMAP::CL_EXPUNGE); - $this->stream = false; - $this->uid_cache = null; - return $result; - } - return false; - } - - /** - * Check if the current session is connected - * - * @return bool - */ - public function connected(): bool { - return boolval($this->stream); + * @return Response + */ + public function logout(): Response { + return $this->response()->wrap(function($response) { + /** @var Response $response */ + if ($this->stream) { + $this->uid_cache = []; + $response->addCommand("imap_close"); + if (\imap_close($this->stream, IMAP::CL_EXPUNGE)) { + $this->stream = false; + return [ + 0 => "BYE Logging out\r\n", + 1 => "TAG" . $response->Noun() . " OK Logout completed (0.001 + 0.000 secs).\r\n", + ]; + } + $this->stream = false; + } + return []; + }); } /** @@ -169,7 +179,7 @@ public function connected(): bool { * * @throws MethodNotSupportedException */ - public function getCapabilities(): array { + public function getCapabilities(): Response { throw new MethodNotSupportedException(); } @@ -177,10 +187,10 @@ public function getCapabilities(): array { * Change the current folder * @param string $folder change to this folder * - * @return bool|array see examineOrselect() + * @return Response see examineOrselect() * @throws RuntimeException */ - public function selectFolder(string $folder = 'INBOX') { + public function selectFolder(string $folder = 'INBOX'): Response { $flags = IMAP::OP_READONLY; if (in_array($this->protocol, ["pop3", "nntp"])) { $flags = IMAP::NIL; @@ -189,138 +199,210 @@ public function selectFolder(string $folder = 'INBOX') { throw new RuntimeException("failed to reopen stream."); } - \imap_reopen($this->stream, $this->getAddress().$folder, $flags, 3); - $this->uid_cache = null; - return $this->examineFolder($folder); + return $this->response("imap_reopen")->wrap(function($response) use ($folder, $flags) { + /** @var Response $response */ + \imap_reopen($this->stream, $this->getAddress() . $folder, $flags, 3); + $this->uid_cache = []; + + $status = $this->examineFolder($folder); + $response->stack($status); + + return $status->data(); + }); } /** * Examine a given folder * @param string $folder examine this folder * - * @return bool|array + * @return Response * @throws RuntimeException */ - public function examineFolder(string $folder = 'INBOX') { - if (strpos($folder, ".") === 0) { + public function examineFolder(string $folder = 'INBOX'): Response { + if (str_starts_with($folder, ".")) { throw new RuntimeException("Segmentation fault prevented. Folders starts with an illegal char '.'."); } - $folder = $this->getAddress().$folder; - $status = \imap_status($this->stream, $folder, IMAP::SA_ALL); - return [ - "flags" => [], - "exists" => $status->messages, - "recent" => $status->recent, - "unseen" => $status->unseen, - "uidnext" => $status->uidnext, - ]; + return $this->response("imap_status")->wrap(function($response) use ($folder) { + /** @var Response $response */ + $status = \imap_status($this->stream, $this->getAddress() . $folder, IMAP::SA_ALL); + + return $status ? [ + "flags" => [], + "exists" => $status->messages, + "recent" => $status->recent, + "unseen" => $status->unseen, + "uidnext" => $status->uidnext, + ] : []; + }); } /** * Fetch message content - * @param array|int $uids + * @param int|array $uids * @param string $rfc - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return array + * @return Response */ - public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array { - $result = []; - $uids = is_array($uids) ? $uids : [$uids]; - foreach ($uids as $id) { - $result[$id] = \imap_fetchbody($this->stream, $id, "", $uid ? IMAP::ST_UID : IMAP::NIL); - } - return $result; + public function content(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($uids, $uid) { + /** @var Response $response */ + + $result = []; + $uids = is_array($uids) ? $uids : [$uids]; + foreach ($uids as $id) { + $response->addCommand("imap_fetchbody"); + $result[$id] = \imap_fetchbody($this->stream, $id, "", $uid === IMAP::ST_UID ? IMAP::ST_UID : IMAP::NIL); + } + + return $result; + }); } /** * Fetch message headers - * @param array|int $uids + * @param int|array $uids * @param string $rfc - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return array + * @return Response */ - public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array { - $result = []; - $uids = is_array($uids) ? $uids : [$uids]; - foreach ($uids as $id) { - $result[$id] = \imap_fetchheader($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL); - } - return $result; + public function headers(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($uids, $uid) { + /** @var Response $response */ + + $result = []; + $uids = is_array($uids) ? $uids : [$uids]; + foreach ($uids as $id) { + $response->addCommand("imap_fetchheader"); + $result[$id] = \imap_fetchheader($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL); + } + + return $result; + }); } /** * Fetch message flags - * @param array|int $uids - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. - * - * @return array - */ - public function flags($uids, $uid = IMAP::ST_UID): array { - $result = []; - $uids = is_array($uids) ? $uids : [$uids]; - foreach ($uids as $id) { - $raw_flags = \imap_fetch_overview($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL); - $flags = []; - if (is_array($raw_flags) && isset($raw_flags[0])) { - $raw_flags = (array) $raw_flags[0]; - foreach($raw_flags as $flag => $value) { - if ($value === 1 && in_array($flag, ["size", "uid", "msgno", "update"]) === false){ - $flags[] = "\\".ucfirst($flag); + * @param int|array $uids + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * + * @return Response + */ + public function flags(int|array $uids, int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($uids, $uid) { + /** @var Response $response */ + + $result = []; + $uids = is_array($uids) ? $uids : [$uids]; + foreach ($uids as $id) { + $response->addCommand("imap_fetch_overview"); + $raw_flags = \imap_fetch_overview($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL); + $flags = []; + if (is_array($raw_flags) && isset($raw_flags[0])) { + $raw_flags = (array)$raw_flags[0]; + foreach ($raw_flags as $flag => $value) { + if ($value === 1 && in_array($flag, ["size", "uid", "msgno", "update"]) === false) { + $flags[] = "\\" . ucfirst($flag); + } } } + $result[$id] = $flags; } - $result[$uid] = $flags; - } - return $result; + return $result; + }); + } + + /** + * Fetch message sizes + * @param int|array $uids + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * + * @return Response + */ + public function sizes(int|array $uids, int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($uids, $uid) { + /** @var Response $response */ + $result = []; + $uids = is_array($uids) ? $uids : [$uids]; + $uid_text = implode("','", $uids); + $response->addCommand("imap_fetch_overview"); + if ($uid == IMAP::ST_UID) { + $raw_overview = \imap_fetch_overview($this->stream, $uid_text, IMAP::FT_UID); + } else { + $raw_overview = \imap_fetch_overview($this->stream, $uid_text); + } + if ($raw_overview !== false) { + foreach ($raw_overview as $overview_element) { + $overview_element = (array)$overview_element; + $result[$overview_element[$uid == IMAP::ST_UID ? 'uid' : 'msgno']] = $overview_element['size']; + } + } + return $result; + }); } /** * Get uid for a given id * @param int|null $id message number * - * @return array|string message number for given message or all messages as array + * @return Response message number for given message or all messages as array */ - public function getUid($id = null) { - if ($id === null) { - if ($this->enable_uid_cache && $this->uid_cache) { - return $this->uid_cache; - } + public function getUid(int $id = null): Response { + return $this->response()->wrap(function($response) use ($id) { + /** @var Response $response */ + if ($id === null) { + if ($this->enable_uid_cache && $this->uid_cache) { + return $this->uid_cache; + } + + $overview = $this->overview("1:*"); + $response->stack($overview); + $uids = []; + foreach ($overview->data() as $set) { + $uids[$set->msgno] = $set->uid; + } - $overview = $this->overview("1:*"); - $uids = []; - foreach($overview as $set){ - $uids[$set->msgno] = $set->uid; + $this->setUidCache($uids); + return $uids; } - $this->setUidCache($uids); - return $uids; - } + $response->addCommand("imap_uid"); + $uid = \imap_uid($this->stream, $id); + if ($uid) { + return $uid; + } - return \imap_uid($this->stream, $id); + return []; + }); } /** * Get a message number for a uid * @param string $id uid * - * @return int message number + * @return Response message number */ - public function getMessageNumber(string $id): int { - return \imap_msgno($this->stream, $id); + public function getMessageNumber(string $id): Response { + return $this->response("imap_msgno")->wrap(function($response) use ($id) { + /** @var Response $response */ + return \imap_msgno($this->stream, $id); + }); } /** * Get a message overview * @param string $sequence uid sequence - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return array + * @return Response */ - public function overview(string $sequence, $uid = IMAP::ST_UID): array { - return \imap_fetch_overview($this->stream, $sequence,$uid ? IMAP::ST_UID : IMAP::NIL); + public function overview(string $sequence, int|string $uid = IMAP::ST_UID): Response { + return $this->response("imap_fetch_overview")->wrap(function($response) use ($sequence, $uid) { + /** @var Response $response */ + return \imap_fetch_overview($this->stream, $sequence, $uid ? IMAP::ST_UID : IMAP::NIL) ?: []; + }); } /** @@ -328,52 +410,65 @@ public function overview(string $sequence, $uid = IMAP::ST_UID): array { * @param string $reference mailbox reference for list * @param string $folder mailbox name match with wildcards * - * @return array folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..)) - * @throws RuntimeException + * @return Response folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..)) */ - public function folders(string $reference = '', string $folder = '*'): array { - $result = []; + public function folders(string $reference = '', string $folder = '*'): Response { + return $this->response("imap_getmailboxes")->wrap(function($response) use ($reference, $folder) { + /** @var Response $response */ + $result = []; - $items = \imap_getmailboxes($this->stream, $this->getAddress(), $reference.$folder); - if(is_array($items)){ - foreach ($items as $item) { - $name = $this->decodeFolderName($item->name); - $result[$name] = ['delimiter' => $item->delimiter, 'flags' => []]; + $items = \imap_getmailboxes($this->stream, $this->getAddress(), $reference . $folder); + if (is_array($items)) { + foreach ($items as $item) { + $name = $this->decodeFolderName($item->name); + $result[$name] = ['delimiter' => $item->delimiter, 'flags' => []]; + } + } else { + throw new RuntimeException(\imap_last_error()); } - }else{ - throw new RuntimeException(\imap_last_error()); - } - return $result; + return $result; + }); } /** * Manage flags - * @param array $flags flags to set, add or remove - see $mode + * @param array|string $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 - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. - * @param null $item unused attribute + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param string|null $item unused attribute * - * @return bool|array new flags if $silent is false, else true or false depending on success + * @return Response new flags if $silent is false, else true or false depending on success */ - public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null) { + public function store(array|string $flags, int $from, int $to = null, string $mode = null, bool $silent = true, int|string $uid = IMAP::ST_UID, string $item = null): Response { $flag = trim(is_array($flags) ? implode(" ", $flags) : $flags); - if ($mode == "+"){ - $status = \imap_setflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL); - }else{ - $status = \imap_clearflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL); - } + return $this->response()->wrap(function($response) use ($mode, $from, $flag, $uid, $silent) { + /** @var Response $response */ - if ($silent === true) { - return $status; - } + if ($mode == "+") { + $response->addCommand("imap_setflag_full"); + $status = \imap_setflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL); + } else { + $response->addCommand("imap_clearflag_full"); + $status = \imap_clearflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL); + } + + if ($silent === true) { + if ($status) { + return [ + "TAG" . $response->Noun() . " OK Store completed (0.001 + 0.000 secs).\r\n" + ]; + } + return []; + } - return $this->flags($from); + return $this->flags($from); + }); } /** @@ -381,19 +476,29 @@ public function store(array $flags, int $from, $to = null, $mode = null, bool $s * @param string $folder name of target folder * @param string $message full message content * @param array|null $flags flags for new message - * @param string $date date for new message + * @param mixed $date date for new message * - * @return bool success + * @return Response */ - public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool { - if ($date != null) { - if ($date instanceof \Carbon\Carbon){ - $date = $date->format('d-M-Y H:i:s O'); + public function appendMessage(string $folder, string $message, array $flags = null, mixed $date = null): Response { + return $this->response("imap_append")->wrap(function($response) use ($folder, $message, $flags, $date) { + /** @var Response $response */ + if ($date != null) { + if ($date instanceof \Carbon\Carbon) { + $date = $date->format('d-M-Y H:i:s O'); + } + if (\imap_append($this->stream, $this->getAddress() . $folder, $message, $flags, $date)) { + return [ + "OK Append completed (0.001 + 0.000 secs).\r\n" + ]; + } + } else if (\imap_append($this->stream, $this->getAddress() . $folder, $message, $flags)) { + return [ + "OK Append completed (0.001 + 0.000 secs).\r\n" + ]; } - return \imap_append($this->stream, $folder, $message, $flags, $date); - } - - return \imap_append($this->stream, $folder, $message, $flags); + return []; + }); } /** @@ -402,30 +507,48 @@ public function appendMessage(string $folder, string $message, $flags = null, $d * @param $from * @param int|null $to if null only one message ($from) is fetched, else it's the * last message, INF means last message available - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return bool success + * @return Response */ - public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool { - return \imap_mail_copy($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL); + public function copyMessage(string $folder, $from, int $to = null, int|string $uid = IMAP::ST_UID): Response { + return $this->response("imap_mail_copy")->wrap(function($response) use ($from, $folder, $uid) { + /** @var Response $response */ + + if (\imap_mail_copy($this->stream, $from, $this->getAddress() . $folder, $uid ? IMAP::ST_UID : IMAP::NIL)) { + return [ + "TAG" . $response->Noun() . " OK Copy completed (0.001 + 0.000 secs).\r\n" + ]; + } + throw new ImapBadRequestException("Invalid ID $from"); + }); } /** * Copy multiple messages to the target folder * @param array $messages List of message identifiers * @param string $folder Destination folder - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. - * - * @return array|bool Tokens if operation successful, false if an error occurred - */ - public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) { - foreach($messages as $msg) { - if (!$this->copyMessage($folder, $msg, null, $uid)) { - return false; + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * + * @return Response Tokens if operation successful, false if an error occurred + */ + public function copyManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($messages, $folder, $uid) { + /** @var Response $response */ + foreach ($messages as $msg) { + $copy_response = $this->copyMessage($folder, $msg, null, $uid); + $response->stack($copy_response); + if (empty($copy_response->data())) { + return [ + "TAG" . $response->Noun() . " BAD Copy failed (0.001 + 0.000 secs).\r\n", + "Invalid ID $msg\r\n" + ]; + } } - } - - return $messages; + return [ + "TAG" . $response->Noun() . " OK Copy completed (0.001 + 0.000 secs).\r\n" + ]; + }); } /** @@ -434,30 +557,46 @@ public function copyManyMessages(array $messages, string $folder, $uid = IMAP::S * @param $from * @param int|null $to if null only one message ($from) is fetched, else it's the * last message, INF means last message available - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return bool success + * @return Response success */ - public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool { - return \imap_mail_move($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL); + public function moveMessage(string $folder, $from, int $to = null, int|string $uid = IMAP::ST_UID): Response { + return $this->response("imap_mail_move")->wrap(function($response) use ($from, $folder, $uid) { + if (\imap_mail_move($this->stream, $from, $this->getAddress() . $folder, $uid ? IMAP::ST_UID : IMAP::NIL)) { + return [ + "TAG" . $response->Noun() . " OK Move completed (0.001 + 0.000 secs).\r\n" + ]; + } + throw new ImapBadRequestException("Invalid ID $from"); + }); } /** * Move multiple messages to the target folder * @param array $messages List of message identifiers * @param string $folder Destination folder - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. - * - * @return array|bool Tokens if operation successful, false if an error occurred - */ - public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) { - foreach($messages as $msg) { - if (!$this->moveMessage($folder, $msg, null, $uid)) { - return false; + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * + * @return Response Tokens if operation successful, false if an error occurred + * @throws ImapBadRequestException + */ + public function moveManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response { + return $this->response()->wrap(function($response) use ($messages, $folder, $uid) { + foreach ($messages as $msg) { + $move_response = $this->moveMessage($folder, $msg, null, $uid); + $response = $response->include($response); + if (empty($move_response->data())) { + return [ + "TAG" . $response->Noun() . " BAD Move failed (0.001 + 0.000 secs).\r\n", + "Invalid ID $msg\r\n" + ]; + } } - } - - return $messages; + return [ + "TAG" . $response->Noun() . " OK Move completed (0.001 + 0.000 secs).\r\n" + ]; + }); } /** @@ -465,11 +604,11 @@ public function moveManyMessages(array $messages, string $folder, $uid = IMAP::S * Ref.: https://datatracker.ietf.org/doc/html/rfc2971 * * @param null $ids - * @return array|bool|void|null + * @return Response * * @throws MethodNotSupportedException */ - public function ID($ids = null) { + public function ID($ids = null): Response { throw new MethodNotSupportedException(); } @@ -477,10 +616,14 @@ public function ID($ids = null) { * Create a new folder (and parent folders if needed) * @param string $folder folder name * - * @return bool success + * @return Response */ - public function createFolder(string $folder): bool { - return \imap_createmailbox($this->stream, $folder); + public function createFolder(string $folder): Response { + return $this->response("imap_createmailbox")->wrap(function($response) use ($folder) { + return \imap_createmailbox($this->stream, $this->getAddress() . $folder) ? [ + 0 => "TAG" . $response->Noun() . " OK Create completed (0.004 + 0.000 + 0.003 secs).\r\n", + ] : []; + }); } /** @@ -488,20 +631,28 @@ public function createFolder(string $folder): bool { * @param string $old old name * @param string $new new name * - * @return bool success + * @return Response */ - public function renameFolder(string $old, string $new): bool { - return \imap_renamemailbox($this->stream, $old, $new); + public function renameFolder(string $old, string $new): Response { + return $this->response("imap_renamemailbox")->wrap(function($response) use ($old, $new) { + return \imap_renamemailbox($this->stream, $this->getAddress() . $old, $this->getAddress() . $new) ? [ + 0 => "TAG" . $response->Noun() . " OK Move completed (0.004 + 0.000 + 0.003 secs).\r\n", + ] : []; + }); } /** * Delete a folder * @param string $folder folder name * - * @return bool success + * @return Response */ - public function deleteFolder(string $folder): bool { - return \imap_deletemailbox($this->stream, $folder); + public function deleteFolder(string $folder): Response { + return $this->response("imap_deletemailbox")->wrap(function($response) use ($folder) { + return \imap_deletemailbox($this->stream, $this->getAddress() . $folder) ? [ + 0 => "OK Delete completed (0.004 + 0.000 + 0.003 secs).\r\n", + ] : []; + }); } /** @@ -510,7 +661,7 @@ public function deleteFolder(string $folder): bool { * * @throws MethodNotSupportedException */ - public function subscribeFolder(string $folder): bool { + public function subscribeFolder(string $folder): Response { throw new MethodNotSupportedException(); } @@ -520,17 +671,21 @@ public function subscribeFolder(string $folder): bool { * * @throws MethodNotSupportedException */ - public function unsubscribeFolder(string $folder): bool { + public function unsubscribeFolder(string $folder): Response { throw new MethodNotSupportedException(); } /** * Apply session saved changes to the server * - * @return bool success + * @return Response */ - public function expunge(): bool { - return \imap_expunge($this->stream); + public function expunge(): Response { + return $this->response("imap_expunge")->wrap(function($response) { + return \imap_expunge($this->stream) ? [ + 0 => "TAG" . $response->Noun() . " OK Expunge completed (0.001 + 0.000 secs).\r\n", + ] : []; + }); } /** @@ -538,7 +693,7 @@ public function expunge(): bool { * * @throws MethodNotSupportedException */ - public function noop(): bool { + public function noop(): Response { throw new MethodNotSupportedException(); } @@ -563,29 +718,29 @@ public function done() { /** * Search for matching messages * @param array $params - * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. + * @param int|string $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers. * - * @return array message ids + * @return Response message ids */ - public function search(array $params, $uid = IMAP::ST_UID): array { - $result = \imap_search($this->stream, $params[0], $uid ? IMAP::ST_UID : IMAP::NIL); - if ($result === false) { - return []; - } - return $result; + public function search(array $params, int|string $uid = IMAP::ST_UID): Response { + return $this->response("imap_search")->wrap(function($response) use ($params, $uid) { + $response->setCanBeEmpty(true); + $result = \imap_search($this->stream, $params[0], $uid ? IMAP::ST_UID : IMAP::NIL); + return $result ?: []; + }); } /** * Enable the debug mode */ - public function enableDebug(){ + public function enableDebug() { $this->debug = true; } /** * Disable the debug mode */ - public function disableDebug(){ + public function disableDebug() { $this->debug = false; } @@ -597,8 +752,8 @@ public function disableDebug(){ * * @return array|false|string|string[]|null */ - protected function decodeFolderName($name) { - preg_match('#\{(.*)\}(.*)#', $name, $preg); + protected function decodeFolderName($name): array|bool|string|null { + preg_match('#\{(.*)}(.*)#', $name, $preg); return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP"); } @@ -613,20 +768,26 @@ public function getProtocol(): string { * Retrieve the quota level settings, and usage statics per mailbox * @param $username * - * @return array + * @return Response */ - public function getQuota($username): array { - return \imap_get_quota($this->stream, 'user.'.$username); + public function getQuota($username): Response { + return $this->response("imap_get_quota")->wrap(function($response) use ($username) { + $result = \imap_get_quota($this->stream, 'user.' . $username); + return $result ?: []; + }); } /** * Retrieve the quota settings per user * @param string $quota_root * - * @return array + * @return Response */ - public function getQuotaRoot(string $quota_root = 'INBOX'): array { - return \imap_get_quotaroot($this->stream, $quota_root); + public function getQuotaRoot(string $quota_root = 'INBOX'): Response { + return $this->response("imap_get_quotaroot")->wrap(function($response) use ($quota_root) { + $result = \imap_get_quotaroot($this->stream, $this->getAddress() . $quota_root); + return $result ?: []; + }); } /** @@ -640,4 +801,14 @@ public function setProtocol(string $protocol): LegacyProtocol { $this->protocol = $protocol; return $this; } + + /** + * Create a new Response instance + * @param string|null $command + * + * @return Response + */ + protected function response(?string $command = ""): Response { + return Response::make(0, $command == "" ? [] : [$command], [], $this->debug); + } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Protocol.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Protocol.php index 29d3b0a6f..6fe88ee99 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Protocol.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Protocol.php @@ -25,40 +25,40 @@ abstract class Protocol implements ProtocolInterface { /** * Default connection timeout in seconds */ - protected $connection_timeout = 30; + protected int $connection_timeout = 30; /** * @var boolean */ - protected $debug = false; + protected bool $debug = false; /** * @var boolean */ - protected $enable_uid_cache = true; + protected bool $enable_uid_cache = true; /** - * @var false|\IMAP\Connection|resource + * @var resource */ public $stream = false; /** * Connection encryption method - * @var mixed $encryption + * @var string $encryption */ - protected $encryption = false; + protected string $encryption = ""; /** * Set to false to ignore SSL certificate validation * @var bool */ - protected $cert_validation = true; + protected bool $cert_validation = true; /** * Proxy settings * @var array */ - protected $proxy = [ + protected array $proxy = [ 'socket' => null, 'request_fulluri' => false, 'username' => null, @@ -68,16 +68,16 @@ abstract class Protocol implements ProtocolInterface { /** * Cache for uid of active folder. * - * @var null|array + * @var array */ - protected $uid_cache = null; + protected array $uid_cache = []; /** * Get an available cryptographic method * * @return int */ - public function getCryptoMethod() { + public function getCryptoMethod(): int { // Allow the best TLS version(s) we can $cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT; @@ -95,18 +95,18 @@ public function getCryptoMethod() { /** * Enable SSL certificate validation * - * @return $this + * @return Protocol */ - public function enableCertValidation() { + public function enableCertValidation(): Protocol { $this->cert_validation = true; return $this; } /** * Disable SSL certificate validation - * @return $this + * @return Protocol */ - public function disableCertValidation() { + public function disableCertValidation(): Protocol { $this->cert_validation = false; return $this; } @@ -115,9 +115,9 @@ public function disableCertValidation() { * Set SSL certificate validation * @var int $cert_validation * - * @return $this + * @return Protocol */ - public function setCertValidation($cert_validation) { + public function setCertValidation(int $cert_validation): Protocol { $this->cert_validation = $cert_validation; return $this; } @@ -127,7 +127,7 @@ public function setCertValidation($cert_validation) { * * @return bool */ - public function getCertValidation() { + public function getCertValidation(): bool { return $this->cert_validation; } @@ -135,9 +135,9 @@ public function getCertValidation() { * Set connection proxy settings * @var array $options * - * @return $this + * @return Protocol */ - public function setProxy($options) { + public function setProxy(array $options): Protocol { foreach ($this->proxy as $key => $val) { if (isset($options[$key])) { $this->proxy[$key] = $options[$key]; @@ -152,19 +152,19 @@ public function setProxy($options) { * * @return array */ - public function getProxy() { + public function getProxy(): array { return $this->proxy; } /** * Prepare socket options - * @var string $transport - * * @return array + *@var string $transport + * */ - private function defaultSocketOptions($transport) { + private function defaultSocketOptions(string $transport): array { $options = []; - if ($this->encryption != false) { + if ($this->encryption) { $options["ssl"] = [ 'verify_peer_name' => $this->getCertValidation(), 'verify_peer' => $this->getCertValidation(), @@ -194,10 +194,10 @@ private function defaultSocketOptions($transport) { * @param int $port of IMAP server, default is 143 (993 for ssl) * @param int $timeout timeout in seconds for initiating session * - * @return resource|boolean The socket created. + * @return resource The socket created. * @throws ConnectionFailedException */ - protected function createStream($transport, $host, $port, $timeout) { + public function createStream($transport, string $host, int $port, int $timeout) { $socket = "$transport://$host:$port"; $stream = stream_socket_client($socket, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, @@ -216,20 +216,22 @@ protected function createStream($transport, $host, $port, $timeout) { } /** + * Get the current connection timeout + * * @return int */ - public function getConnectionTimeout() { + public function getConnectionTimeout(): int { return $this->connection_timeout; } /** + * Set the connection timeout * @param int $connection_timeout + * * @return Protocol */ - public function setConnectionTimeout($connection_timeout) { - if ($connection_timeout !== null) { - $this->connection_timeout = $connection_timeout; - } + public function setConnectionTimeout(int $connection_timeout): Protocol { + $this->connection_timeout = $connection_timeout; return $this; } @@ -239,7 +241,7 @@ public function setConnectionTimeout($connection_timeout) { * * @return string */ - public function getUIDKey($uid) { + public function getUIDKey(int|string $uid): string { if ($uid == IMAP::ST_UID || $uid == IMAP::FT_UID) { return "UID"; } @@ -250,7 +252,14 @@ public function getUIDKey($uid) { return ""; } - public function buildUIDCommand($command, $uid) { + /** + * Build a UID / MSGN command + * @param string $command + * @param int|string $uid + * + * @return string + */ + public function buildUIDCommand(string $command, int|string $uid): string { return trim($this->getUIDKey($uid)." ".$command); } @@ -259,9 +268,9 @@ public function buildUIDCommand($command, $uid) { * * @param array|null $uids */ - public function setUidCache($uids) { + public function setUidCache(?array $uids) { if (is_null($uids)) { - $this->uid_cache = null; + $this->uid_cache = []; return; } @@ -269,17 +278,89 @@ public function setUidCache($uids) { $uid_cache = []; foreach ($uids as $uid) { - $uid_cache[$messageNumber++] = $uid; + $uid_cache[$messageNumber++] = (int)$uid; } $this->uid_cache = $uid_cache; } - public function enableUidCache() { + /** + * Enable the uid cache + * + * @return void + */ + public function enableUidCache(): void { $this->enable_uid_cache = true; } - public function disableUidCache() { + /** + * Disable the uid cache + * + * @return void + */ + public function disableUidCache(): void { $this->enable_uid_cache = false; } + + /** + * Set the encryption method + * @param string $encryption + * + * @return void + */ + public function setEncryption(string $encryption): void { + $this->encryption = $encryption; + } + + /** + * Get the encryption method + * @return string + */ + public function getEncryption(): string { + return $this->encryption; + } + + /** + * Check if the current session is connected + * + * @return bool + */ + public function connected(): bool { + return (bool)$this->stream; + } + + /** + * Retrieves header/meta data from the resource stream + * + * @return array + */ + public function meta(): array { + if (!$this->stream) { + return [ + "crypto" => [ + "protocol" => "", + "cipher_name" => "", + "cipher_bits" => 0, + "cipher_version" => "", + ], + "timed_out" => true, + "blocked" => true, + "eof" => true, + "stream_type" => "tcp_socket/unknown", + "mode" => "c", + "unread_bytes" => 0, + "seekable" => false, + ]; + } + return stream_get_meta_data($this->stream); + } + + /** + * Get the resource stream + * + * @return mixed + */ + public function getStream(): mixed { + return $this->stream; + } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php index 97a2fe3d9..c02d78003 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php @@ -13,9 +13,10 @@ namespace Webklex\PHPIMAP\Connection\Protocols; use ErrorException; -use Webklex\PHPIMAP\Client; use Webklex\PHPIMAP\Exceptions\AuthFailedException; use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException; use Webklex\PHPIMAP\Exceptions\MessageNotFoundException; use Webklex\PHPIMAP\Exceptions\RuntimeException; @@ -30,6 +31,10 @@ interface ProtocolInterface { /** * Public destructor + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException */ public function __destruct(); @@ -42,34 +47,42 @@ public function __destruct(); * @throws ConnectionFailedException * @throws RuntimeException */ - public function connect(string $host, $port = null); + public function connect(string $host, ?int $port = null); /** * Login to a new session. * * @param string $user username * @param string $password password - * @return bool success + * + * @return Response + * * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException */ - public function login(string $user, string $password): bool; + public function login(string $user, string $password): Response; /** * Authenticate your current session. * @param string $user username * @param string $token access token * - * @return bool|mixed + * @return Response * @throws AuthFailedException */ - public function authenticate(string $user, string $token); + public function authenticate(string $user, string $token): Response; /** * Logout of the current server session * - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException */ - public function logout(): bool; + public function logout(): Response; /** * Check if the current session is connected @@ -81,95 +94,106 @@ public function connected(): bool; /** * Get an array of available capabilities * - * @return array list of capabilities + * @return Response containing a list of capabilities * @throws RuntimeException */ - public function getCapabilities(): array; + public function getCapabilities(): Response; /** * Change the current folder - * * @param string $folder change to this folder - * @return bool|array see examineOrSelect() + * + * @return Response see examineOrSelect() * @throws RuntimeException */ - public function selectFolder(string $folder = 'INBOX'); + public function selectFolder(string $folder = 'INBOX'): Response; /** * Examine a given folder - * * @param string $folder - * @return bool|array + * + * @return Response * @throws RuntimeException */ - public function examineFolder(string $folder = 'INBOX'); + public function examineFolder(string $folder = 'INBOX'): Response; /** * Fetch message headers - * @param array|int $uids + * @param int|array $uids * @param string $rfc * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException */ - public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array; + public function content(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response; /** * Fetch message headers - * @param array|int $uids + * @param int|array $uids * @param string $rfc * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException */ - public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array; + public function headers(int|array $uids, string $rfc = "RFC822", int|string $uid = IMAP::ST_UID): Response; /** * Fetch message flags - * @param array|int $uids + * @param int|array $uids * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException */ - public function flags($uids, $uid = IMAP::ST_UID): array; + public function flags(int|array $uids, int|string $uid = IMAP::ST_UID): Response; + + /** + * Fetch message sizes + * @param int|array $uids + * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use + * message numbers instead. + * + * @return Response + * @throws RuntimeException + */ + public function sizes(int|array $uids, int|string $uid = IMAP::ST_UID): Response; /** * Get uid for a given id * @param int|null $id message number * - * @return array|string message number for given message or all messages as array + * @return Response containing a message number for given message or all messages as array * @throws MessageNotFoundException */ - public function getUid($id = null); + public function getUid(?int $id = null): Response; /** * Get a message number for a uid * @param string $id uid * - * @return int message number + * @return Response containing the message number * @throws MessageNotFoundException */ - public function getMessageNumber(string $id): int; + public function getMessageNumber(string $id): Response; /** * Get a list of available folders * @param string $reference mailbox reference for list * @param string $folder mailbox / folder name match with wildcards * - * @return array mailboxes that matched $folder as array(globalName => array('delim' => .., 'flags' => ..)) + * @return Response containing mailboxes that matched $folder as array(globalName => array('delim' => .., 'flags' => ..)) * @throws RuntimeException */ - public function folders(string $reference = '', string $folder = '*'): array; + public function folders(string $reference = '', string $folder = '*'): Response; /** * Set message flags - * @param array $flags flags to set, add or remove + * @param array|string $flags flags to set, add or remove * @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 @@ -177,12 +201,12 @@ public function folders(string $reference = '', string $folder = '*'): array; * @param bool $silent if false the return values are the new flags for the wanted messages * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. - * @param null|string $item command used to store a flag + * @param string|null $item command used to store a flag * - * @return bool|array new flags if $silent is false, else true or false depending on success + * @return Response containing the new flags if $silent is false, else true or false depending on success * @throws RuntimeException */ - public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null); + public function store(array|string $flags, int $from, ?int $to = null, ?string $mode = null, bool $silent = true, int|string $uid = IMAP::ST_UID, ?string $item = null): Response; /** * Append a new message to given folder @@ -191,10 +215,10 @@ public function store(array $flags, int $from, $to = null, $mode = null, bool $s * @param array|null $flags flags for new message * @param string|null $date date for new message * - * @return bool success + * @return Response * @throws RuntimeException */ - public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool; + public function appendMessage(string $folder, string $message, ?array $flags = null, ?string $date = null): Response; /** * Copy message set from current folder to other folder @@ -206,10 +230,10 @@ public function appendMessage(string $folder, string $message, $flags = null, $d * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return bool success + * @return Response * @throws RuntimeException */ - public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool; + public function copyMessage(string $folder, $from, ?int $to = null, int|string $uid = IMAP::ST_UID): Response; /** * Copy multiple messages to the target folder @@ -218,10 +242,10 @@ public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_U * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array|bool Tokens if operation successful, false if an error occurred + * @return Response Tokens if operation successful, false if an error occurred * @throws RuntimeException */ - public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID); + public function copyManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response; /** * Move a message set from current folder to another folder @@ -232,9 +256,9 @@ public function copyManyMessages(array $messages, string $folder, $uid = IMAP::S * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return bool success + * @return Response */ - public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool; + public function moveMessage(string $folder, $from, ?int $to = null, int|string $uid = IMAP::ST_UID): Response; /** * Move multiple messages to the target folder @@ -244,67 +268,76 @@ public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_U * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array|bool Tokens if operation successful, false if an error occurred + * @return Response Tokens if operation successful, false if an error occurred * @throws RuntimeException */ - public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID); + public function moveManyMessages(array $messages, string $folder, int|string $uid = IMAP::ST_UID): Response; /** * Exchange identification information * Ref.: https://datatracker.ietf.org/doc/html/rfc2971 * * @param null $ids - * @return array|bool|void|null + * @return Response * * @throws RuntimeException */ - public function ID($ids = null); + public function ID($ids = null): Response; /** * Create a new folder * * @param string $folder folder name - * @return bool success + * @return Response * @throws RuntimeException */ - public function createFolder(string $folder): bool; + public function createFolder(string $folder): Response; /** * Rename an existing folder * * @param string $old old name * @param string $new new name - * @return bool success + * @return Response * @throws RuntimeException */ - public function renameFolder(string $old, string $new): bool; + public function renameFolder(string $old, string $new): Response; /** * Delete a folder * * @param string $folder folder name - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function deleteFolder(string $folder): bool; + public function deleteFolder(string $folder): Response; /** * Subscribe to a folder * * @param string $folder folder name - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function subscribeFolder(string $folder): bool; + public function subscribeFolder(string $folder): Response; /** * Unsubscribe from a folder + * * @param string $folder folder name + * @return Response * - * @return bool success + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function unsubscribeFolder(string $folder): bool; + public function unsubscribeFolder(string $folder): Response; /** * Send idle command @@ -322,37 +355,43 @@ public function done(); /** * Apply session saved changes to the server * - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function expunge(): bool; + public function expunge(): Response; /** * Retrieve the quota level settings, and usage statics per mailbox * @param $username * - * @return array + * @return Response * @throws RuntimeException */ - public function getQuota($username): array; + public function getQuota($username): Response; /** * Retrieve the quota settings per user * * @param string $quota_root * - * @return array + * @return Response * @throws ConnectionFailedException */ - public function getQuotaRoot(string $quota_root = 'INBOX'): array; + public function getQuotaRoot(string $quota_root = 'INBOX'): Response; /** * Send noop command * - * @return bool success + * @return Response + * + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException */ - public function noop(): bool; + public function noop(): Response; /** * Do a search request @@ -361,10 +400,10 @@ public function noop(): bool; * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array message ids + * @return Response containing the message ids * @throws RuntimeException */ - public function search(array $params, $uid = IMAP::ST_UID): array; + public function search(array $params, int|string $uid = IMAP::ST_UID): Response; /** * Get a message overview @@ -372,12 +411,12 @@ public function search(array $params, $uid = IMAP::ST_UID): array; * @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use * message numbers instead. * - * @return array + * @return Response * @throws RuntimeException * @throws MessageNotFoundException * @throws InvalidMessageDateException */ - public function overview(string $sequence, $uid = IMAP::ST_UID): array; + public function overview(string $sequence, int|string $uid = IMAP::ST_UID): Response; /** * Enable the debug mode @@ -404,5 +443,5 @@ public function disableUidCache(); * * @param array|null $uids */ - public function setUidCache($uids); + public function setUidCache(?array $uids); } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Response.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Response.php new file mode 100644 index 000000000..9a30d56da --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Connection/Protocols/Response.php @@ -0,0 +1,417 @@ +debug = $debug; + $this->noun = $noun > 0 ? $noun : (int)str_replace(".", "", (string)microtime(true)); + } + + /** + * Make a new response instance + * @param int $noun + * @param array $commands + * @param array $responses + * @param bool $debug + * + * @return Response + */ + public static function make(int $noun, array $commands = [], array $responses = [], bool $debug = false): Response { + return (new self($noun, $debug))->setCommands($commands)->setResponse($responses); + } + + /** + * Create a new empty response + * @param bool $debug + * + * @return Response + */ + public static function empty(bool $debug = false): Response { + return (new self(0, $debug)); + } + + /** + * Stack another response + * @param Response $response + * + * @return void + */ + public function stack(Response $response): void { + $this->response_stack[] = $response; + } + + /** + * Get the associated response stack + * + * @return array + */ + public function getStack(): array { + return $this->response_stack; + } + + /** + * Get all assigned commands + * + * @return array + */ + public function getCommands(): array { + return $this->commands; + } + + /** + * Add a new command + * @param string $command + * + * @return Response + */ + public function addCommand(string $command): Response { + $this->commands[] = $command; + return $this; + } + + /** + * Set and overwrite all commands + * @param array $commands + * + * @return Response + */ + public function setCommands(array $commands): Response { + $this->commands = $commands; + return $this; + } + + /** + * Get all set errors + * + * @return array + */ + public function getErrors(): array { + $errors = $this->errors; + foreach($this->getStack() as $response) { + $errors = array_merge($errors, $response->getErrors()); + } + return $errors; + } + + /** + * Set and overwrite all existing errors + * @param array $errors + * + * @return Response + */ + public function setErrors(array $errors): Response { + $this->errors = $errors; + return $this; + } + + /** + * Set the response + * @param string $error + * + * @return Response + */ + public function addError(string $error): Response { + $this->errors[] = $error; + return $this; + } + + /** + * Set the response + * @param array $response + * + * @return Response + */ + public function addResponse(mixed $response): Response { + $this->response[] = $response; + return $this; + } + + /** + * Set the response + * @param array $response + * + * @return Response + */ + public function setResponse(array $response): Response { + $this->response = $response; + return $this; + } + + /** + * Get the assigned response + * + * @return array + */ + public function getResponse(): array { + return $this->response; + } + + /** + * Set the result data + * @param mixed $result + * + * @return Response + */ + public function setResult(mixed $result): Response { + $this->result = $result; + return $this; + } + + /** + * Wrap a result bearing action + * @param callable $callback + * + * @return Response + */ + public function wrap(callable $callback): Response { + $this->result = call_user_func($callback, $this); + return $this; + } + + /** + * Get the response data + * + * @return mixed + */ + public function data(): mixed { + if ($this->result !== null) { + return $this->result; + } + return $this->getResponse(); + } + + /** + * Get the response data as array + * + * @return array + */ + public function array(): array { + $data = $this->data(); + if(is_array($data)){ + return $data; + } + return [$data]; + } + + /** + * Get the response data as string + * + * @return string + */ + public function string(): string { + $data = $this->data(); + if(is_array($data)){ + return implode(" ", $data); + } + return (string)$data; + } + + /** + * Get the response data as integer + * + * @return int + */ + public function integer(): int { + $data = $this->data(); + if(is_array($data) && isset($data[0])){ + return (int)$data[0]; + } + return (int)$data; + } + + /** + * Get the response data as boolean + * + * @return bool + */ + public function boolean(): bool { + return (bool)$this->data(); + } + + /** + * Validate and retrieve the response data + * + * @throws ResponseException + */ + public function validatedData(): mixed { + return $this->validate()->data(); + } + + /** + * Validate the response date + * + * @throws ResponseException + */ + public function validate(): Response { + if ($this->failed()) { + throw ResponseException::make($this, $this->debug); + } + return $this; + } + + /** + * Check if the Response can be considered successful + * + * @return bool + */ + public function successful(): bool { + foreach(array_merge($this->getResponse(), $this->array()) as $data) { + if (!$this->verify_data($data)) { + return false; + } + } + foreach($this->getStack() as $response) { + if (!$response->successful()) { + return false; + } + } + return ($this->boolean() || $this->canBeEmpty()) && !$this->getErrors(); + } + + + /** + * Check if the Response can be considered failed + * @param mixed $data + * + * @return bool + */ + public function verify_data(mixed $data): bool { + if (is_array($data)) { + foreach ($data as $line) { + if (is_array($line)) { + if(!$this->verify_data($line)){ + return false; + } + }else{ + if (!$this->verify_line((string)$line)) { + return false; + } + } + } + }else{ + if (!$this->verify_line((string)$data)) { + return false; + } + } + return true; + } + + /** + * Verify a single line + * @param string $line + * + * @return bool + */ + public function verify_line(string $line): bool { + return !str_starts_with($line, "TAG".$this->noun." BAD ") && !str_starts_with($line, "TAG".$this->noun." NO "); + } + + /** + * Check if the Response can be considered failed + * + * @return bool + */ + public function failed(): bool { + return !$this->successful(); + } + + /** + * Get the Response noun + * + * @return int + */ + public function Noun(): int { + return $this->noun; + } + + /** + * Set the Response to be allowed to be empty + * @param bool $can_be_empty + * + * @return $this + */ + public function setCanBeEmpty(bool $can_be_empty): Response { + $this->can_be_empty = $can_be_empty; + return $this; + } + + /** + * Check if the Response can be empty + * + * @return bool + */ + public function canBeEmpty(): bool { + return $this->can_be_empty; + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/EncodingAliases.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/EncodingAliases.php index 9140640e1..888fc7fab 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/EncodingAliases.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/EncodingAliases.php @@ -25,7 +25,7 @@ class EncodingAliases { * * @var array */ - private static $aliases = [ + private static array $aliases = [ /* |-------------------------------------------------------------------------- | Email encoding aliases @@ -107,6 +107,8 @@ class EncodingAliases { "ibm864" => "IBM864", "utf-8" => "UTF-8", "utf-7" => "UTF-7", + "utf-7-imap" => "UTF7-IMAP", + "utf7-imap" => "UTF7-IMAP", "shift_jis" => "Shift_JIS", "big5" => "Big5", "euc-jp" => "EUC-JP", @@ -466,17 +468,124 @@ class EncodingAliases { ]; /** - * Returns proper encoding mapping, if exsists. If it doesn't, return unchanged $encoding + * Returns proper encoding mapping, if exists. If it doesn't, return unchanged $encoding * @param string|null $encoding * @param string|null $fallback * * @return string */ - public static function get($encoding, string $fallback = null): string { + public static function get(?string $encoding, string $fallback = null): string { if (isset(self::$aliases[strtolower($encoding ?? '')])) { return self::$aliases[strtolower($encoding ?? '')]; } - return $fallback !== null ? $fallback : $encoding; + return $fallback ?: $encoding; + } + + + /** + * Convert the encoding of a string + * @param $str + * @param string $from + * @param string $to + * + * @return mixed + */ + public static function convert($str, string $from = "ISO-8859-2", string $to = "UTF-8"): mixed { + $from = self::get($from, self::detectEncoding($str)); + $to = self::get($to, self::detectEncoding($str)); + + if ($from === $to) { + return $str; + } + + // We don't need to do convertEncoding() if charset is ASCII (us-ascii): + // ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded + // https://stackoverflow.com/a/11303410 + // + // us-ascii is the same as ASCII: + // ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA) + // prefers the updated name US-ASCII, which clarifies that this system was developed in the US and + // based on the typographical symbols predominantly in use there. + // https://en.wikipedia.org/wiki/ASCII + // + // convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken. + if (strtolower($from) == 'us-ascii' && $to == 'UTF-8') { + return $str; + } + + try { + if (function_exists('iconv') && !self::isUtf7($from) && !self::isUtf7($to)) { + return iconv($from, $to, $str); + } + if (!$from) { + return mb_convert_encoding($str, $to); + } + return mb_convert_encoding($str, $to, $from); + } catch (\Exception $e) { + if (str_contains($from, '-')) { + $from = str_replace('-', '', $from); + return self::convert($str, $from, $to); + } + return $str; + } + } + + /** + * Attempts to detect the encoding of a string + * @param string $string + * + * @return string + */ + public static function detectEncoding(string $string): string { + $encoding = mb_detect_encoding($string, array_filter(self::getEncodings(), function($value){ + return !in_array($value, [ + 'ISO-8859-6-I', 'ISO-8859-6-E', 'ISO-8859-8-I', 'ISO-8859-8-E', + 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', 'ISO-IR-111',"ISO-2022-CN", + "windows-1250", "windows-1253", "windows-1255", "windows-1256", "windows-1257", "windows-1258", + "IBM852", "IBM855", "IBM857", "IBM866", "IBM864", "IBM862", "KOI8-R", "KOI8-U", + "TIS-620", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", + "VISCII", "T.61-8bit", "Big5-HKSCS", "windows-874", "macintosh", "ISO-8859-12", "ISO-8859-7", + "IMAP-UTF-7" + ]); + }), true); + if ($encoding === false) { + $encoding = 'UTF-8'; + } + return $encoding; + } + + /** + * Returns all available encodings + * + * @return array + */ + public static function getEncodings(): array { + $encodings = []; + foreach (self::$aliases as $encoding) { + if (!in_array($encoding, $encodings)) { + $encodings[] = $encoding; + } + } + return $encodings; + } + + /** + * Returns true if the encoding is UTF-7 like + * @param string $encoding + * + * @return bool + */ + public static function isUtf7(string $encoding): bool { + return str_contains(str_replace("-", "", strtolower($encoding)), "utf7"); + } + + /** + * Check if an encoding is supported + * @param string $encoding + * + * @return bool + */ + public static function has(string $encoding): bool { + return isset(self::$aliases[strtolower($encoding)]); } - } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FlagNewEvent.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FlagNewEvent.php index 3fea518e7..18e264fb0 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FlagNewEvent.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FlagNewEvent.php @@ -22,17 +22,18 @@ class FlagNewEvent extends Event { /** @var Message $message */ - public $message; + public Message $message; /** @var string $flag */ - public $flag; + public string $flag; /** * Create a new event instance. - * @var mixed[] $arguments + * @var array $arguments + * * @return void */ - public function __construct($arguments) { + public function __construct(array $arguments) { $this->message = $arguments[0]; $this->flag = $arguments[1]; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderMovedEvent.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderMovedEvent.php index b8b9c7cb2..746ad1233 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderMovedEvent.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderMovedEvent.php @@ -22,16 +22,18 @@ class FolderMovedEvent extends Event { /** @var Folder $old_folder */ - public $old_folder; + public Folder $old_folder; + /** @var Folder $new_folder */ - public $new_folder; + public Folder $new_folder; /** * Create a new event instance. * @var Folder[] $folders + * * @return void */ - public function __construct($folders) { + public function __construct(array $folders) { $this->old_folder = $folders[0]; $this->new_folder = $folders[1]; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderNewEvent.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderNewEvent.php index d16bbbd67..0c576cade 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderNewEvent.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/FolderNewEvent.php @@ -22,14 +22,15 @@ class FolderNewEvent extends Event { /** @var Folder $folder */ - public $folder; + public Folder $folder; /** * Create a new event instance. * @var Folder[] $folders + * * @return void */ - public function __construct($folders) { + public function __construct(array $folders) { $this->folder = $folders[0]; } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageMovedEvent.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageMovedEvent.php index 261ea0197..ace645d7f 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageMovedEvent.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageMovedEvent.php @@ -22,16 +22,18 @@ class MessageMovedEvent extends Event { /** @var Message $old_message */ - public $old_message; + public Message $old_message; + /** @var Message $new_message */ - public $new_message; + public Message $new_message; /** * Create a new event instance. * @var Message[] $messages + * * @return void */ - public function __construct($messages) { + public function __construct(array $messages) { $this->old_message = $messages[0]; $this->new_message = $messages[1]; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageNewEvent.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageNewEvent.php index 1487e28d6..38892c496 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageNewEvent.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Events/MessageNewEvent.php @@ -22,14 +22,15 @@ class MessageNewEvent extends Event { /** @var Message $message */ - public $message; + public Message $message; /** * Create a new event instance. * @var Message[] $messages + * * @return void */ - public function __construct($messages) { + public function __construct(array $messages) { $this->message = $messages[0]; } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Exceptions/ImapBadRequestException.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Exceptions/ImapBadRequestException.php new file mode 100644 index 000000000..511718d51 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Exceptions/ImapBadRequestException.php @@ -0,0 +1,24 @@ +getErrors() as $error) { + $message .= "\t- $error\n"; + } + + if(!$response->data()) { + $message .= "\t- Empty response\n"; + } + + if ($debug) { + $message .= self::debug_message($response); + } + + foreach($response->getStack() as $_response) { + $exception = self::make($_response, $debug, $exception); + } + + return new self($message."Error occurred", 0, $exception); + } + + /** + * Generate a debug message containing all commands send and responses received + * @param Response $response + * + * @return string + */ + protected static function debug_message(Response $response): string { + $commands = $response->getCommands(); + $message = "Commands send:\n"; + if ($commands) { + foreach($commands as $command) { + $message .= "\t".str_replace("\r\n", "\\r\\n", $command)."\n"; + } + }else{ + $message .= "\tNo command send!\n"; + } + + $responses = $response->getResponse(); + $message .= "Responses received:\n"; + if ($responses) { + foreach($responses as $_response) { + if (is_array($_response)) { + foreach($_response as $value) { + $message .= "\t".str_replace("\r\n", "\\r\\n", "$value")."\n"; + } + }else{ + $message .= "\t".str_replace("\r\n", "\\r\\n", "$_response")."\n"; + } + } + }else{ + $message .= "\tNo responses received!\n"; + } + + return $message; + } +} diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Folder.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Folder.php index 01e59cc84..c9ca395d0 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Folder.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Folder.php @@ -13,8 +13,17 @@ namespace Webklex\PHPIMAP; use Carbon\Carbon; +use Webklex\PHPIMAP\Connection\Protocols\Response; +use Webklex\PHPIMAP\Exceptions\AuthFailedException; use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; +use Webklex\PHPIMAP\Exceptions\EventNotFoundException; +use Webklex\PHPIMAP\Exceptions\FolderFetchingException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; +use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException; +use Webklex\PHPIMAP\Exceptions\MessageNotFoundException; use Webklex\PHPIMAP\Exceptions\NotSupportedCapabilityException; +use Webklex\PHPIMAP\Exceptions\ResponseException; use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\Query\WhereQuery; use Webklex\PHPIMAP\Support\FolderCollection; @@ -33,57 +42,57 @@ class Folder { * * @var Client */ - protected $client; + protected Client $client; /** * Folder full path * * @var string */ - public $path; + public string $path; /** * Folder name * * @var string */ - public $name; + public string $name; /** - * Folder fullname + * Folder full name * * @var string */ - public $full_name; + public string $full_name; /** * Children folders * - * @var FolderCollection|array + * @var FolderCollection */ - public $children = []; + public FolderCollection $children; /** * Delimiter for folder * * @var string */ - public $delimiter; + public string $delimiter; /** - * Indicates if folder can't containg any "children". + * Indicates if folder can't contain any "children". * CreateFolder won't work on this folder. * * @var boolean */ - public $no_inferiors; + public bool $no_inferiors; /** * Indicates if folder is only container, not a mailbox - you can't open it. * * @var boolean */ - public $no_select; + public bool $no_select; /** * Indicates if folder is marked. This means that it may contain new messages since the last time it was checked. @@ -91,26 +100,26 @@ class Folder { * * @var boolean */ - public $marked; + public bool $marked; /** - * Indicates if folder containg any "children". + * Indicates if folder contains any "children". * Not provided by all IMAP servers. * * @var boolean */ - public $has_children; + public bool $has_children; /** - * Indicates if folder refers to other. + * Indicates if folder refers to others. * Not provided by all IMAP servers. * * @var boolean */ - public $referral; + public bool $referral; /** @var array */ - public $status; + public array $status; /** * Folder constructor. @@ -126,9 +135,11 @@ public function __construct(Client $client, string $folder_name, string $delimit $this->events["folder"] = $client->getDefaultEvents("folder"); $this->setDelimiter($delimiter); - $this->path = $folder_name; - $this->full_name = $this->decodeName($folder_name); - $this->name = $this->getSimpleName($this->delimiter, $this->full_name); + $this->path = $folder_name; + $this->full_name = $this->decodeName($folder_name); + $this->name = $this->getSimpleName($this->delimiter, $this->full_name); + $this->children = new FolderCollection(); + $this->has_children = false; $this->parseAttributes($attributes); } @@ -138,8 +149,12 @@ public function __construct(Client $client, string $folder_name, string $delimit * @param string[] $extensions * * @return WhereQuery - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ResponseException */ public function query(array $extensions = []): WhereQuery { $this->getClient()->checkConnection(); @@ -154,8 +169,12 @@ public function query(array $extensions = []): WhereQuery { * @param string[] $extensions * * @return WhereQuery - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ResponseException */ public function search(array $extensions = []): WhereQuery { return $this->query($extensions); @@ -166,8 +185,12 @@ public function search(array $extensions = []): WhereQuery { * @param string[] $extensions * * @return WhereQuery - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ResponseException */ public function messages(array $extensions = []): WhereQuery { return $this->query($extensions); @@ -184,25 +207,39 @@ public function hasChildren(): bool { /** * Set children. - * @param FolderCollection|array $children + * @param FolderCollection $children * - * @return self + * @return Folder */ - public function setChildren($children = []): Folder { + public function setChildren(FolderCollection $children): Folder { $this->children = $children; return $this; } + /** + * Get children. + * + * @return FolderCollection + */ + public function getChildren(): FolderCollection { + return $this->children; + } + /** * Decode name. * It converts UTF7-IMAP encoding to UTF-8. * @param $name * - * @return array|false|string|string[]|null + * @return string|array|bool|string[]|null */ - protected function decodeName($name) { - return mb_convert_encoding($name, "UTF-8", "UTF7-IMAP"); + protected function decodeName($name): string|array|bool|null { + $parts = []; + foreach (explode($this->delimiter, $name) as $item) { + $parts[] = EncodingAliases::convert($item, "UTF7-IMAP", "UTF-8"); + } + + return implode($this->delimiter, $parts); } /** @@ -210,11 +247,10 @@ protected function decodeName($name) { * @param $delimiter * @param $full_name * - * @return mixed + * @return string|bool */ - protected function getSimpleName($delimiter, $full_name) { + protected function getSimpleName($delimiter, $full_name): string|bool { $arr = explode($delimiter, $full_name); - return end($arr); } @@ -222,11 +258,11 @@ protected function getSimpleName($delimiter, $full_name) { * Parse attributes and set it to object properties. * @param $attributes */ - protected function parseAttributes($attributes) { + protected function parseAttributes($attributes): void { $this->no_inferiors = in_array('\NoInferiors', $attributes); - $this->no_select = in_array('\NoSelect', $attributes); - $this->marked = in_array('\Marked', $attributes); - $this->referral = in_array('\Referral', $attributes); + $this->no_select = in_array('\NoSelect', $attributes); + $this->marked = in_array('\Marked', $attributes); + $this->referral = in_array('\Referral', $attributes); $this->has_children = in_array('\HasChildren', $attributes); } @@ -235,16 +271,20 @@ protected function parseAttributes($attributes) { * @param string $new_name * @param boolean $expunge * - * @return bool + * @return array * @throws ConnectionFailedException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function move(string $new_name, bool $expunge = true): bool { + public function move(string $new_name, bool $expunge = true): array { $this->client->checkConnection(); - $status = $this->client->getConnection()->renameFolder($this->full_name, $new_name); - if($expunge) $this->client->expunge(); + $status = $this->client->getConnection()->renameFolder($this->full_name, $new_name)->validatedData(); + if ($expunge) $this->client->expunge(); $folder = $this->client->getFolder($new_name); $event = $this->getEvent("folder", "moved"); @@ -259,39 +299,48 @@ public function move(string $new_name, bool $expunge = true): bool { * * @return array * @throws ConnectionFailedException - * @throws Exceptions\InvalidMessageDateException - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws InvalidMessageDateException + * @throws MessageNotFoundException + * @throws ResponseException */ public function overview(string $sequence = null): array { $this->client->openFolder($this->path); $sequence = $sequence === null ? "1:*" : $sequence; - $uid = ClientManager::get('options.sequence', IMAP::ST_MSGN) == IMAP::ST_UID; - return $this->client->getConnection()->overview($sequence, $uid); + $uid = ClientManager::get('options.sequence', IMAP::ST_MSGN); + $response = $this->client->getConnection()->overview($sequence, $uid); + return $response->validatedData(); } /** * Append a string message to the current mailbox * @param string $message * @param array|null $options - * @param string|null|Carbon $internal_date + * @param string|Carbon|null $internal_date * - * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @return array + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function appendMessage(string $message, array $options = null, $internal_date = null): bool { + public function appendMessage(string $message, array $options = null, Carbon|string $internal_date = null): array { /** * Check if $internal_date is parsed. If it is null it should not be set. Otherwise, the message can't be stored. * If this parameter is set, it will set the INTERNALDATE on the appended message. The parameter should be a * date string that conforms to the rfc2060 specifications for a date_time value or be a Carbon object. */ - if ($internal_date instanceof Carbon){ + if ($internal_date instanceof Carbon) { $internal_date = $internal_date->format('d-M-Y H:i:s O'); } - return $this->client->getConnection()->appendMessage($this->path, $message, $options, $internal_date); + return $this->client->getConnection()->appendMessage($this->path, $message, $options, $internal_date)->validatedData(); } /** @@ -299,13 +348,17 @@ public function appendMessage(string $message, array $options = null, $internal_ * @param string $new_name * @param boolean $expunge * - * @return bool + * @return array * @throws ConnectionFailedException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws RuntimeException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws AuthFailedException + * @throws ResponseException */ - public function rename(string $new_name, bool $expunge = true): bool { + public function rename(string $new_name, bool $expunge = true): array { return $this->move($new_name, $expunge); } @@ -313,14 +366,22 @@ public function rename(string $new_name, bool $expunge = true): bool { * Delete the current folder * @param boolean $expunge * - * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException - * @throws Exceptions\EventNotFoundException - */ - public function delete(bool $expunge = true): bool { - $status = $this->client->getConnection()->deleteFolder($this->path); - if($expunge) $this->client->expunge(); + * @return array + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws EventNotFoundException + * @throws AuthFailedException + * @throws ResponseException + */ + public function delete(bool $expunge = true): array { + $status = $this->client->getConnection()->deleteFolder($this->path)->validatedData(); + if ($this->client->getActiveFolder() == $this->path){ + $this->client->setActiveFolder(null); + } + + if ($expunge) $this->client->expunge(); $event = $this->getEvent("folder", "deleted"); $event::dispatch($this); @@ -331,90 +392,101 @@ public function delete(bool $expunge = true): bool { /** * Subscribe the current folder * - * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @return array + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function subscribe(): bool { + public function subscribe(): array { $this->client->openFolder($this->path); - return $this->client->getConnection()->subscribeFolder($this->path); + return $this->client->getConnection()->subscribeFolder($this->path)->validatedData(); } /** * Unsubscribe the current folder * - * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @return array + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function unsubscribe(): bool { + public function unsubscribe(): array { $this->client->openFolder($this->path); - return $this->client->getConnection()->unsubscribeFolder($this->path); + return $this->client->getConnection()->unsubscribeFolder($this->path)->validatedData(); } /** * Idle the current connection - * @param callable $callback + * @param callable $callback function(Message $message) gets called if a new message is received * @param integer $timeout max 1740 seconds - recommended by rfc2177 §3. Should not be lower than the servers "* OK Still here" message interval - * @param boolean $auto_reconnect try to reconnect on connection close (@deprecated is no longer required) * * @throws ConnectionFailedException - * @throws Exceptions\InvalidMessageDateException - * @throws Exceptions\MessageContentFetchingException - * @throws Exceptions\MessageHeaderFetchingException - * @throws Exceptions\RuntimeException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\MessageFlagException - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\NotSupportedCapabilityException - */ - public function idle(callable $callback, int $timeout = 300, bool $auto_reconnect = false) { + * @throws RuntimeException + * @throws AuthFailedException + * @throws NotSupportedCapabilityException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + */ + public function idle(callable $callback, int $timeout = 300): void { $this->client->setTimeout($timeout); - if (!in_array("IDLE", $this->client->getConnection()->getCapabilities())) { - throw new NotSupportedCapabilityException("IMAP server does not support IDLE"); + + if (!in_array("IDLE", $this->client->getConnection()->getCapabilities()->validatedData())) { + throw new Exceptions\NotSupportedCapabilityException("IMAP server does not support IDLE"); } - $this->client->openFolder($this->path, true); - $connection = $this->client->getConnection(); - $connection->idle(); + + $idle_client = $this->client->clone(); + $idle_client->connect(); + $idle_client->openFolder($this->path, true); + $idle_client->getConnection()->idle(); + + $last_action = Carbon::now()->addSeconds($timeout); $sequence = ClientManager::get('options.sequence', IMAP::ST_MSGN); while (true) { - try { - // This polymorphic call is fine - Protocol::idle() will throw an exception beforehand - $line = $connection->nextLine(); - - if (($pos = strpos($line, "EXISTS")) !== false) { - $connection->done(); - $msgn = (int) substr($line, 2, $pos -2); - - $this->client->openFolder($this->path, true); - $message = $this->query()->getMessageByMsgn($msgn); - $message->setSequence($sequence); - $callback($message); - - $event = $this->getEvent("message", "new"); - $event::dispatch($message); - $connection->idle(); - } elseif (strpos($line, "OK") === false) { - $connection->done(); - $connection->idle(); - } - }catch (Exceptions\RuntimeException $e) { - if(strpos($e->getMessage(), "empty response") >= 0 && $connection->connected()) { - $connection->done(); - $connection->idle(); - continue; - } - if(strpos($e->getMessage(), "connection closed") === false) { - throw $e; + // This polymorphic call is fine - Protocol::idle() will throw an exception beforehand + $line = $idle_client->getConnection()->nextLine(Response::empty()); + + if (($pos = strpos($line, "EXISTS")) !== false) { + $msgn = (int)substr($line, 2, $pos - 2); + + // Check if the stream is still alive or should be considered stale + if (!$this->client->isConnected() || $last_action->isBefore(Carbon::now())) { + // Reset the connection before interacting with it. Otherwise, the resource might be stale which + // would result in a stuck interaction. If you know of a way of detecting a stale resource, please + // feel free to improve this logic. I tried a lot but nothing seem to work reliably... + // Things that didn't work: + // - Closing the resource with fclose() + // - Verifying the resource with stream_get_meta_data() + // - Bool validating the resource stream (e.g.: (bool)$stream) + // - Sending a NOOP command + // - Sending a null package + // - Reading a null package + // - Catching the fs warning + + // This polymorphic call is fine - Protocol::idle() will throw an exception beforehand + $this->client->getConnection()->reset(); + // Establish a new connection + $this->client->connect(); } + $last_action = Carbon::now()->addSeconds($timeout); - $this->client->reconnect(); + // Always reopen the folder - otherwise the new message number isn't known to the current remote session $this->client->openFolder($this->path, true); - $connection = $this->client->getConnection(); - $connection->idle(); + $message = $this->query()->getMessageByMsgn($msgn); + $message->setSequence($sequence); + $callback($message); + + $event = $this->getEvent("message", "new"); + $event::dispatch($message); } } } @@ -423,19 +495,26 @@ public function idle(callable $callback, int $timeout = 300, bool $auto_reconnec * Get folder status information * * @return array - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ public function getStatus(): array { return $this->examine(); } /** - * @throws RuntimeException * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ - public function loadStatus(): Folder - { + public function loadStatus(): Folder { $this->status = $this->getStatus(); return $this; } @@ -444,12 +523,30 @@ public function loadStatus(): Folder * Examine the current folder * * @return array - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws AuthFailedException + * @throws ResponseException */ public function examine(): array { - $result = $this->client->getConnection()->examineFolder($this->path); - return is_array($result) ? $result : []; + return $this->client->getConnection()->examineFolder($this->path)->validatedData(); + } + + /** + * Select the current folder + * + * @return array + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException + */ + public function select(): array { + return $this->client->getConnection()->selectFolder($this->path)->validatedData(); } /** @@ -465,8 +562,8 @@ public function getClient(): Client { * Set the delimiter * @param $delimiter */ - public function setDelimiter($delimiter){ - if(in_array($delimiter, [null, '', ' ', false]) === true) { + public function setDelimiter($delimiter): void { + if (in_array($delimiter, [null, '', ' ', false]) === true) { $delimiter = ClientManager::get('options.delimiter', '/'); } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Header.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Header.php index b9bcc0571..9c8ae046c 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Header.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Header.php @@ -29,47 +29,38 @@ class Header { * * @var string $raw */ - public $raw = ""; + public string $raw = ""; /** * Attribute holder * * @var Attribute[]|array $attributes */ - protected $attributes = []; + protected array $attributes = []; /** * Config holder * * @var array $config */ - protected $config = []; + protected array $config = []; /** * Fallback Encoding * * @var string */ - public $fallback_encoding = 'UTF-8'; - - /** - * Convert parsed values to attributes - * - * @var bool - */ - protected $attributize = false; + public string $fallback_encoding = 'UTF-8'; /** * Header constructor. * @param string $raw_header - * @param boolean $attributize * * @throws InvalidMessageDateException */ - public function __construct(string $raw_header, bool $attributize = true) { + public function __construct(string $raw_header) { $this->raw = $raw_header; $this->config = ClientManager::get('options'); - $this->attributize = $attributize; $this->parse(); } @@ -108,14 +99,26 @@ public function __get($name) { * Get a specific header attribute * @param $name * - * @return Attribute|mixed + * @return Attribute */ - public function get($name) { + public function get($name): Attribute { + $name = str_replace(["-", " "], "_", strtolower($name)); if (isset($this->attributes[$name])) { return $this->attributes[$name]; } - return null; + return new Attribute($name); + } + + /** + * Check if a specific attribute exists + * @param string $name + * + * @return bool + */ + public function has(string $name): bool { + $name = str_replace(["-", " "], "_", strtolower($name)); + return isset($this->attributes[$name]); } /** @@ -124,25 +127,11 @@ public function get($name) { * @param array|mixed $value * @param boolean $strict * - * @return Attribute + * @return Attribute|array */ - public function set(string $name, $value, bool $strict = false) { + public function set(string $name, mixed $value, bool $strict = false): Attribute|array { if (isset($this->attributes[$name]) && $strict === false) { - if ($this->attributize) { - $this->attributes[$name]->add($value, true); - } else { - if (isset($this->attributes[$name])) { - if (!is_array($this->attributes[$name])) { - $this->attributes[$name] = [$this->attributes[$name], $value]; - } else { - $this->attributes[$name][] = $value; - } - } else { - $this->attributes[$name] = $value; - } - } - } elseif (!$this->attributize) { - $this->attributes[$name] = $value; + $this->attributes[$name]->add($value, true); } else { $this->attributes[$name] = new Attribute($name, $value); } @@ -156,7 +145,7 @@ public function set(string $name, $value, bool $strict = false) { * * @return mixed|null */ - public function find($pattern) { + public function find($pattern): mixed { if (preg_match_all($pattern, $this->raw, $matches)) { if (isset($matches[1])) { if (count($matches[1]) > 0) { @@ -172,7 +161,7 @@ public function find($pattern) { * * @return string|null */ - public function getBoundary() { + public function getBoundary(): ?string { $regex = $this->config["boundary"] ?? "/boundary=(.*?(?=;)|(.*))/i"; $boundary = $this->find($regex); @@ -198,7 +187,7 @@ private function clearBoundaryString(string $str): string { * * @throws InvalidMessageDateException */ - protected function parse() { + protected function parse(): void { $header = $this->rfc822_parse_headers($this->raw); $this->extractAddresses($header); @@ -207,11 +196,16 @@ protected function parse() { $this->set("subject", $this->decode($header->subject)); } if (property_exists($header, 'references')) { - $this->set("references", $this->decode($header->references)); + $this->set("references", array_map(function ($item) { + return str_replace(['<', '>'], '', $item); + }, explode(" ", $header->references))); } if (property_exists($header, 'message_id')) { $this->set("message_id", str_replace(['<', '>'], '', $header->message_id)); } + if (property_exists($header, 'in_reply_to')) { + $this->set("in_reply_to", str_replace(['<', '>'], '', $header->in_reply_to)); + } $this->parseDate($header); foreach ($header as $key => $value) { @@ -232,30 +226,30 @@ protected function parse() { * * @return object */ - public function rfc822_parse_headers($raw_headers) { + public function rfc822_parse_headers($raw_headers): object { $headers = []; $imap_headers = []; if (extension_loaded('imap') && $this->config["rfc822"]) { - $raw_imap_headers = (array)\imap_rfc822_parse_headers($this->raw); + $raw_imap_headers = (array)\imap_rfc822_parse_headers($raw_headers); foreach ($raw_imap_headers as $key => $values) { - $key = str_replace("-", "_", $key); + $key = strtolower(str_replace("-", "_", $key)); $imap_headers[$key] = $values; } } $lines = explode("\r\n", preg_replace("/\r\n\s/", ' ', $raw_headers)); $prev_header = null; foreach ($lines as $line) { - if (substr($line, 0, 1) === "\n") { + if (str_starts_with($line, "\n")) { $line = substr($line, 1); } - if (substr($line, 0, 1) === "\t") { + if (str_starts_with($line, "\t")) { $line = substr($line, 1); $line = trim(rtrim($line)); if ($prev_header !== null) { $headers[$prev_header][] = $line; } - } elseif (substr($line, 0, 1) === " ") { + } elseif (str_starts_with($line, " ")) { $line = substr($line, 1); $line = trim(rtrim($line)); if ($prev_header !== null) { @@ -271,7 +265,7 @@ public function rfc822_parse_headers($raw_headers) { } else { if (($pos = strpos($line, ":")) > 0) { $key = trim(rtrim(strtolower(substr($line, 0, $pos)))); - $key = str_replace("-", "_", $key); + $key = strtolower(str_replace("-", "_", $key)); $value = trim(rtrim(substr($line, $pos + 1))); if (isset($headers[$key])) { @@ -285,9 +279,11 @@ public function rfc822_parse_headers($raw_headers) { } foreach ($headers as $key => $values) { - if (isset($imap_headers[$key])) continue; + if (isset($imap_headers[$key])) { + continue; + } $value = null; - switch ($key) { + switch ((string)$key) { case 'from': case 'to': case 'cc': @@ -354,9 +350,9 @@ public function mime_header_decode(string $text): array { * @return bool */ private function notDecoded($encoded, $decoded): bool { - return 0 === strpos($decoded, '=?') + return str_starts_with($decoded, '=?') && strlen($decoded) - 2 === strpos($decoded, '?=') - && false !== strpos($encoded, $decoded); + && str_contains($encoded, $decoded); } /** @@ -367,8 +363,7 @@ private function notDecoded($encoded, $decoded): bool { * * @return mixed|string */ - public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") { - + public function convertEncoding($str, string $from = "ISO-8859-2", string $to = "UTF-8"): mixed { $from = EncodingAliases::get($from, $this->fallback_encoding); $to = EncodingAliases::get($to, $this->fallback_encoding); @@ -376,38 +371,7 @@ public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") { return $str; } - // We don't need to do convertEncoding() if charset is ASCII (us-ascii): - // ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded - // https://stackoverflow.com/a/11303410 - // - // us-ascii is the same as ASCII: - // ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA) - // prefers the updated name US-ASCII, which clarifies that this system was developed in the US and - // based on the typographical symbols predominantly in use there. - // https://en.wikipedia.org/wiki/ASCII - // - // convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken. - if (strtolower($from) == 'us-ascii' && $to == 'UTF-8') { - return $str; - } - - try { - if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') { - return iconv($from, $to, $str); - } else { - if (!$from) { - return mb_convert_encoding($str, $to); - } - return mb_convert_encoding($str, $to, $from); - } - } catch (\Exception $e) { - if (strstr($from, '-')) { - $from = str_replace('-', '', $from); - return $this->convertEncoding($str, $from, $to); - } else { - return $str; - } - } + return EncodingAliases::convert($str, $from, $to); } /** @@ -416,7 +380,7 @@ public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") { * * @return string */ - public function getEncoding($structure): string { + public function getEncoding(object|string $structure): string { if (property_exists($structure, 'parameters')) { foreach ($structure->parameters as $parameter) { if (strtolower($parameter->attribute) == "charset") { @@ -440,7 +404,7 @@ public function getEncoding($structure): string { * @return bool */ private function is_uft8($value): bool { - return strpos(strtolower($value), '=?utf-8?') === 0; + return str_starts_with(strtolower($value), '=?utf-8?'); } /** @@ -449,7 +413,7 @@ private function is_uft8($value): bool { * * @return mixed */ - private function decode($value) { + public function decode(mixed $value): mixed { if (is_array($value)) { return $this->decodeArray($value); } @@ -457,29 +421,24 @@ private function decode($value) { $decoder = $this->config['decoder']['message']; if ($value !== null) { - $is_utf8_base = $this->is_uft8($value); - - if ($decoder === 'utf-8' && extension_loaded('imap')) { - $value = \imap_utf8($value); - $is_utf8_base = $this->is_uft8($value); - if ($is_utf8_base) { - $value = mb_decode_mimeheader($value); + if ($decoder === 'utf-8') { + $decoded_values = $this->mime_header_decode($value); + $tempValue = ""; + foreach ($decoded_values as $decoded_value) { + $tempValue .= $this->convertEncoding($decoded_value->text, $decoded_value->charset); } - if ($this->notDecoded($original_value, $value)) { - $decoded_value = $this->mime_header_decode($value); - if (count($decoded_value) > 0) { - if (property_exists($decoded_value[0], "text")) { - $value = $decoded_value[0]->text; - } - } + if ($tempValue) { + $value = $tempValue; + } else if (extension_loaded('imap')) { + $value = \imap_utf8($value); + }else if (function_exists('iconv_mime_decode')){ + $value = iconv_mime_decode($value, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, "UTF-8"); + }else{ + $value = mb_decode_mimeheader($value); } - } elseif ($decoder === 'iconv' && $is_utf8_base) { - $value = iconv_mime_decode($value); - } elseif ($is_utf8_base) { - $value = mb_decode_mimeheader($value); - } - - if ($this->is_uft8($value)) { + }elseif ($decoder === 'iconv') { + $value = iconv_mime_decode($value, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, "UTF-8"); + }else if ($this->is_uft8($value)) { $value = mb_decode_mimeheader($value); } @@ -507,28 +466,17 @@ private function decodeArray(array $values): array { /** * Try to extract the priority from a given raw header string */ - private function findPriority() { - if (($priority = $this->get("x_priority")) === null) return; - switch ((int)"$priority") { - case IMAP::MESSAGE_PRIORITY_HIGHEST; - $priority = IMAP::MESSAGE_PRIORITY_HIGHEST; - break; - case IMAP::MESSAGE_PRIORITY_HIGH; - $priority = IMAP::MESSAGE_PRIORITY_HIGH; - break; - case IMAP::MESSAGE_PRIORITY_NORMAL; - $priority = IMAP::MESSAGE_PRIORITY_NORMAL; - break; - case IMAP::MESSAGE_PRIORITY_LOW; - $priority = IMAP::MESSAGE_PRIORITY_LOW; - break; - case IMAP::MESSAGE_PRIORITY_LOWEST; - $priority = IMAP::MESSAGE_PRIORITY_LOWEST; - break; - default: - $priority = IMAP::MESSAGE_PRIORITY_UNKNOWN; - break; - } + private function findPriority(): void { + $priority = $this->get("x_priority"); + + $priority = match ((int)"$priority") { + IMAP::MESSAGE_PRIORITY_HIGHEST => IMAP::MESSAGE_PRIORITY_HIGHEST, + IMAP::MESSAGE_PRIORITY_HIGH => IMAP::MESSAGE_PRIORITY_HIGH, + IMAP::MESSAGE_PRIORITY_NORMAL => IMAP::MESSAGE_PRIORITY_NORMAL, + IMAP::MESSAGE_PRIORITY_LOW => IMAP::MESSAGE_PRIORITY_LOW, + IMAP::MESSAGE_PRIORITY_LOWEST => IMAP::MESSAGE_PRIORITY_LOWEST, + default => IMAP::MESSAGE_PRIORITY_UNKNOWN, + }; $this->set("priority", $priority); } @@ -592,7 +540,7 @@ private function decodeAddresses($values): array { * Extract a given part as address array from a given header * @param object $header */ - private function extractAddresses($header) { + private function extractAddresses(object $header): void { foreach (['from', 'to', 'cc', 'bcc', 'reply_to', 'sender'] as $key) { if (property_exists($header, $key)) { $this->set($key, $this->parseAddresses($header->$key)); @@ -627,18 +575,23 @@ private function parseAddresses($list): array { } else { $personalParts = $this->mime_header_decode($address->personal); - if (is_array($personalParts)) { - $address->personal = ''; - foreach ($personalParts as $p) { - $address->personal .= $this->convertEncoding($p->text, $this->getEncoding($p)); - } + $address->personal = ''; + foreach ($personalParts as $p) { + $address->personal .= $this->convertEncoding($p->text, $this->getEncoding($p)); } - if (strpos($address->personal, "'") === 0) { + if (str_starts_with($address->personal, "'")) { $address->personal = str_replace("'", "", $address->personal); } } + if ($address->host == ".SYNTAX-ERROR.") { + $address->host = ""; + } + if ($address->mailbox == "UNEXPECTED_DATA_AFTER_ADDRESS") { + $address->mailbox = ""; + } + $address->mail = ($address->mailbox && $address->host) ? $address->mailbox . '@' . $address->host : false; $address->full = ($address->personal) ? $address->personal . ' <' . $address->mail . '>' : $address->mail; @@ -651,7 +604,7 @@ private function parseAddresses($list): array { /** * Search and extract potential header extensions */ - private function extractHeaderExtensions() { + private function extractHeaderExtensions(): void { foreach ($this->attributes as $key => $value) { if (is_array($value)) { $value = implode(", ", $value); @@ -659,18 +612,44 @@ private function extractHeaderExtensions() { $value = (string)$value; } // Only parse strings and don't parse any attributes like the user-agent - if (($key == "user_agent") === false) { + if (!in_array($key, ["user-agent", "subject"])) { if (($pos = strpos($value, ";")) !== false) { $original = substr($value, 0, $pos); - $this->set($key, trim(rtrim($original)), true); + $this->set($key, trim(rtrim($original))); // Get all potential extensions $extensions = explode(";", substr($value, $pos + 1)); + $previousKey = null; + $previousValue = ''; + foreach ($extensions as $extension) { if (($pos = strpos($extension, "=")) !== false) { $key = substr($extension, 0, $pos); $key = trim(rtrim(strtolower($key))); + $matches = []; + + if (preg_match('/^(?P\w+)\*/', $key, $matches) !== 0) { + $key = $matches['key_name']; + $previousKey = $key; + + $value = substr($extension, $pos + 1); + $value = str_replace('"', "", $value); + $previousValue .= trim(rtrim($value)); + + continue; + } + + if ( + $previousKey !== null + && $previousKey !== $key + && isset($this->attributes[$previousKey]) === false + ) { + $this->set($previousKey, $previousValue); + + $previousValue = ''; + } + if (isset($this->attributes[$key]) === false) { $value = substr($extension, $pos + 1); $value = str_replace('"', "", $value); @@ -678,8 +657,13 @@ private function extractHeaderExtensions() { $this->set($key, $value); } + + $previousKey = $key; } } + if ($previousValue !== '') { + $this->set($previousKey, $previousValue); + } } } } @@ -688,7 +672,7 @@ private function extractHeaderExtensions() { /** * Exception handling for invalid dates * - * Currently known invalid formats: + * Known bad and "invalid" formats: * ^ Datetime ^ Problem ^ Cause * | Mon, 20 Nov 2017 20:31:31 +0800 (GMT+8:00) | Double timezone specification | A Windows feature * | Thu, 8 Nov 2018 08:54:58 -0200 (-02) | @@ -704,7 +688,7 @@ private function extractHeaderExtensions() { * * @throws InvalidMessageDateException */ - private function parseDate($header) { + private function parseDate(object $header): void { if (property_exists($header, 'date')) { $date = $header->date; @@ -715,21 +699,56 @@ private function parseDate($header) { $date = trim(rtrim($date)); try { - if(strpos($date, ' ') !== false){ + if (str_contains($date, ' ')) { $date = str_replace(' ', ' ', $date); } + if (str_contains($date, ' UT ')) { + $date = str_replace(' UT ', ' UTC ', $date); + } $parsed_date = Carbon::parse($date); } catch (\Exception $e) { switch (true) { case preg_match('/([0-9]{4}\.[0-9]{1,2}\.[0-9]{1,2}\-[0-9]{1,2}\.[0-9]{1,2}.[0-9]{1,2})+$/i', $date) > 0: $date = Carbon::createFromFormat("Y.m.d-H.i.s", $date); break; + case preg_match('/([0-9]{2} [A-Z]{3} [0-9]{4} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2} [+-][0-9]{1,4} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2} [+-][0-9]{1,4})+$/i', $date) > 0: + $parts = explode(' ', $date); + array_splice($parts, -2); + $date = implode(' ', $parts); + break; + case preg_match('/([A-Z]{2,4}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4})+$/i', $date) > 0: + $array = explode(',', $date); + array_shift($array); + $date = Carbon::createFromFormat("d M Y H:i:s O", trim(implode(',', $array))); + break; case preg_match('/([0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0: case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0: $date .= 'C'; break; case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}[\,]\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4})+$/i', $date) > 0: $date = str_replace(',', '', $date); + break; + // match case for: Di., 15 Feb. 2022 06:52:44 +0100 (MEZ)/Di., 15 Feb. 2022 06:52:44 +0100 (MEZ) + case preg_match('/([A-Z]{2,3}\.\,\ [0-9]{1,2}\ [A-Z]{2,3}\.\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \([A-Z]{3,4}\))\/([A-Z]{2,3}\.\,\ [0-9]{1,2}\ [A-Z]{2,3}\.\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \([A-Z]{3,4}\))+$/i', $date) > 0: + $dates = explode('/', $date); + $date = array_shift($dates); + $array = explode(',', $date); + array_shift($array); + $date = trim(implode(',', $array)); + $array = explode(' ', $date); + array_pop($array); + $date = trim(implode(' ', $array)); + $date = Carbon::createFromFormat("d M. Y H:i:s O", $date); + break; + // match case for: fr., 25 nov. 2022 06:27:14 +0100/fr., 25 nov. 2022 06:27:14 +0100 + case preg_match('/([A-Z]{2,3}\.\,\ [0-9]{1,2}\ [A-Z]{2,3}\.\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4})\/([A-Z]{2,3}\.\,\ [0-9]{1,2}\ [A-Z]{2,3}\.\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4})+$/i', $date) > 0: + $dates = explode('/', $date); + $date = array_shift($dates); + $array = explode(',', $date); + array_shift($array); + $date = trim(implode(',', $array)); + $date = Carbon::createFromFormat("d M. Y H:i:s O", $date); + break; case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ \+[0-9]{2,4}\ \(\+[0-9]{1,2}\))+$/i', $date) > 0: case preg_match('/([A-Z]{2,3}[\,|\ \,]\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}.*)+$/i', $date) > 0: case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \(.*)\)+$/i', $date) > 0: @@ -764,4 +783,26 @@ public function getAttributes(): array { return $this->attributes; } + /** + * Set all header attributes + * @param array $attributes + * + * @return Header + */ + public function setAttributes(array $attributes): Header { + $this->attributes = $attributes; + return $this; + } + + /** + * Set the configuration used for parsing a raw header + * @param array $config + * + * @return Header + */ + public function setConfig(array $config): Header { + $this->config = $config; + return $this; + } + } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Message.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Message.php index 4137db9a5..09a534f24 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Message.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Message.php @@ -14,12 +14,23 @@ use ReflectionClass; use ReflectionException; +use Webklex\PHPIMAP\Exceptions\AuthFailedException; +use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; +use Webklex\PHPIMAP\Exceptions\EventNotFoundException; +use Webklex\PHPIMAP\Exceptions\FolderFetchingException; +use Webklex\PHPIMAP\Exceptions\GetMessagesFailedException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException; use Webklex\PHPIMAP\Exceptions\MaskNotFoundException; use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException; use Webklex\PHPIMAP\Exceptions\MessageFlagException; use Webklex\PHPIMAP\Exceptions\MessageHeaderFetchingException; +use Webklex\PHPIMAP\Exceptions\MessageNotFoundException; +use Webklex\PHPIMAP\Exceptions\MessageSizeFetchingException; use Webklex\PHPIMAP\Exceptions\MethodNotFoundException; +use Webklex\PHPIMAP\Exceptions\ResponseException; +use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\Support\AttachmentCollection; use Webklex\PHPIMAP\Support\FlagCollection; use Webklex\PHPIMAP\Support\Masks\MessageMask; @@ -35,6 +46,7 @@ * @property integer msglist * @property integer uid * @property integer msgn + * @property integer size * @property Attribute subject * @property Attribute message_id * @property Attribute message_no @@ -52,6 +64,7 @@ * @method integer setMsglist($msglist) * @method integer getUid() * @method integer getMsgn() + * @method integer getSize() * @method Attribute getPriority() * @method Attribute getSubject() * @method Attribute getMessageId() @@ -72,102 +85,102 @@ class Message { /** * Client instance * - * @var Client + * @var ?Client */ - private $client = Client::class; + private ?Client $client = null; /** * Default mask * * @var string $mask */ - protected $mask = MessageMask::class; + protected string $mask = MessageMask::class; /** * Used config * * @var array $config */ - protected $config = []; + protected array $config = []; /** * Attribute holder * * @var Attribute[]|array $attributes */ - protected $attributes = []; + protected array $attributes = []; /** * The message folder path * * @var string $folder_path */ - protected $folder_path; + protected string $folder_path; /** * Fetch body options * - * @var integer + * @var ?integer */ - public $fetch_options = null; + public ?int $fetch_options = null; /** * @var integer */ - protected $sequence = IMAP::NIL; + protected int $sequence = IMAP::NIL; /** * Fetch body options * * @var bool */ - public $fetch_body = null; + public bool $fetch_body = true; /** * Fetch flags options * * @var bool */ - public $fetch_flags = null; + public bool $fetch_flags = true; /** - * @var Header $header + * @var ?Header $header */ - public $header = null; + public ?Header $header = null; /** * Raw message body * - * @var null|string $raw_body + * @var string $raw_body */ - public $raw_body = null; + protected string $raw_body = ""; /** * Message structure * - * @var Structure $structure + * @var ?Structure $structure */ - protected $structure = null; + protected ?Structure $structure = null; /** * Message body components * - * @var array $bodies + * @var array $bodies */ - public $bodies = []; + public array $bodies = []; /** @var AttachmentCollection $attachments */ - public $attachments; + public AttachmentCollection $attachments; /** @var FlagCollection $flags */ - public $flags; + public FlagCollection $flags; /** * A list of all available and supported flags * - * @var array $available_flags + * @var ?array $available_flags */ - private $available_flags = null; + private ?array $available_flags = null; /** * Message constructor. @@ -179,20 +192,23 @@ class Message { * @param boolean $fetch_flags * @param integer|null $sequence * - * @throws Exceptions\ConnectionFailedException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException - * @throws Exceptions\RuntimeException - * @throws MessageHeaderFetchingException * @throws MessageContentFetchingException - * @throws Exceptions\EventNotFoundException * @throws MessageFlagException - * @throws Exceptions\MessageNotFoundException + * @throws MessageHeaderFetchingException + * @throws RuntimeException + * @throws ResponseException */ - public function __construct(int $uid, $msglist, Client $client, int $fetch_options = null, bool $fetch_body = false, bool $fetch_flags = false, int $sequence = null) { + public function __construct(int $uid, ?int $msglist, Client $client, int $fetch_options = null, bool $fetch_body = false, bool $fetch_flags = false, int $sequence = null) { $this->boot(); $default_mask = $client->getDefaultMessageMask(); - if($default_mask != null) { + if ($default_mask != null) { $this->mask = $default_mask; } $this->events["message"] = $client->getDefaultEvents("message"); @@ -237,29 +253,32 @@ public function __construct(int $uid, $msglist, Client $client, int $fetch_optio * @param null $sequence * * @return Message - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException - * @throws ReflectionException * @throws MessageFlagException - * @throws Exceptions\RuntimeException - * @throws Exceptions\MessageNotFoundException + * @throws ReflectionException + * @throws RuntimeException + * @throws ResponseException */ - public static function make(int $uid, $msglist, Client $client, string $raw_header, string $raw_body, array $raw_flags, $fetch_options = null, $sequence = null): Message { + public static function make(int $uid, ?int $msglist, Client $client, string $raw_header, string $raw_body, array $raw_flags, $fetch_options = null, $sequence = null): Message { $reflection = new ReflectionClass(self::class); - /** @var self $instance */ + /** @var Message $instance */ $instance = $reflection->newInstanceWithoutConstructor(); $instance->boot(); $default_mask = $client->getDefaultMessageMask(); - if($default_mask != null) { + if ($default_mask != null) { $instance->setMask($default_mask); } $instance->setEvents([ - "message" => $client->getDefaultEvents("message"), - "flag" => $client->getDefaultEvents("flag"), - ]); + "message" => $client->getDefaultEvents("message"), + "flag" => $client->getDefaultEvents("flag"), + ]); $instance->setFolderPath($client->getFolderPath()); $instance->setSequence($sequence); $instance->setFetchOption($fetch_options); @@ -275,10 +294,75 @@ public static function make(int $uid, $msglist, Client $client, string $raw_head return $instance; } + /** + * Create a new message instance by reading and loading a file or remote location + * + * @throws RuntimeException + * @throws MessageContentFetchingException + * @throws ResponseException + * @throws ImapBadRequestException + * @throws InvalidMessageDateException + * @throws ConnectionFailedException + * @throws ImapServerErrorException + * @throws ReflectionException + * @throws AuthFailedException + * @throws MaskNotFoundException + */ + public static function fromFile($filename): Message { + $blob = file_get_contents($filename); + if ($blob === false) { + throw new RuntimeException("Unable to read file"); + } + return self::fromString($blob); + } + + /** + * Create a new message instance by reading and loading a string + * @param string $blob + * + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws ReflectionException + * @throws ResponseException + * @throws RuntimeException + */ + public static function fromString(string $blob): Message { + $reflection = new ReflectionClass(self::class); + /** @var Message $instance */ + $instance = $reflection->newInstanceWithoutConstructor(); + $instance->boot(); + + $default_mask = ClientManager::getMask("message"); + if($default_mask != ""){ + $instance->setMask($default_mask); + }else{ + throw new MaskNotFoundException("Unknown message mask provided"); + } + + if(!str_contains($blob, "\r\n")){ + $blob = str_replace("\n", "\r\n", $blob); + } + $raw_header = substr($blob, 0, strpos($blob, "\r\n\r\n")); + $raw_body = substr($blob, strlen($raw_header)+4); + + $instance->parseRawHeader($raw_header); + $instance->parseRawBody($raw_body); + + $instance->setUid(0); + + return $instance; + } + /** * Boot a new instance */ - public function boot(){ + public function boot(): void { $this->attributes = []; $this->config = ClientManager::get('options'); @@ -294,22 +378,30 @@ public function boot(){ * @param array $arguments * * @return mixed + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MessageNotFoundException * @throws MethodNotFoundException + * @throws MessageSizeFetchingException + * @throws RuntimeException + * @throws ResponseException */ public function __call(string $method, array $arguments) { - if(strtolower(substr($method, 0, 3)) === 'get') { + if (strtolower(substr($method, 0, 3)) === 'get') { $name = Str::snake(substr($method, 3)); return $this->get($name); - }elseif (strtolower(substr($method, 0, 3)) === 'set') { + } elseif (strtolower(substr($method, 0, 3)) === 'set') { $name = Str::snake(substr($method, 3)); - if(in_array($name, array_keys($this->attributes))) { + if (in_array($name, array_keys($this->attributes))) { return $this->__set($name, array_pop($arguments)); } } - throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported'); + throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported'); } /** @@ -330,6 +422,14 @@ public function __set($name, $value) { * @param $name * * @return Attribute|mixed|null + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MessageNotFoundException + * @throws MessageSizeFetchingException + * @throws RuntimeException + * @throws ResponseException */ public function __get($name) { return $this->get($name); @@ -340,12 +440,34 @@ public function __get($name) { * @param $name * * @return Attribute|mixed|null - */ - public function get($name) { - if(isset($this->attributes[$name])) { + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException + * @throws MessageSizeFetchingException + */ + public function get($name): mixed { + if (isset($this->attributes[$name]) && $this->attributes[$name] !== null) { return $this->attributes[$name]; } + switch ($name){ + case "uid": + $this->attributes[$name] = $this->client->getConnection()->getUid($this->msgn)->validate()->integer(); + return $this->attributes[$name]; + case "msgn": + $this->attributes[$name] = $this->client->getConnection()->getMessageNumber($this->uid)->validate()->integer(); + return $this->attributes[$name]; + case "size": + if (!isset($this->attributes[$name])) { + $this->fetchSize(); + } + return $this->attributes[$name]; + } + return $this->header->get($name); } @@ -355,17 +477,17 @@ public function get($name) { * @return bool */ public function hasTextBody(): bool { - return isset($this->bodies['text']); + return isset($this->bodies['text']) && $this->bodies['text'] !== ""; } /** * Get the Message text body * - * @return mixed + * @return string */ - public function getTextBody() { + public function getTextBody(): string { if (!isset($this->bodies['text'])) { - return null; + return ""; } return $this->bodies['text']; @@ -377,17 +499,17 @@ public function getTextBody() { * @return bool */ public function hasHTMLBody(): bool { - return isset($this->bodies['html']); + return isset($this->bodies['html']) && $this->bodies['html'] !== ""; } /** * Get the Message html body * - * @return string|null + * @return string */ - public function getHTMLBody() { + public function getHTMLBody(): string { if (!isset($this->bodies['html'])) { - return null; + return ""; } return $this->bodies['html']; @@ -396,14 +518,18 @@ public function getHTMLBody() { /** * Parse all defined headers * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException * @throws InvalidMessageDateException * @throws MessageHeaderFetchingException + * @throws ResponseException */ - private function parseHeader() { + private function parseHeader(): void { $sequence_id = $this->getSequenceId(); - $headers = $this->client->getConnection()->headers([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID); + $headers = $this->client->getConnection()->headers([$sequence_id], "RFC822", $this->sequence)->validatedData(); if (!isset($headers[$sequence_id])) { throw new MessageHeaderFetchingException("no headers found", 0); } @@ -416,7 +542,7 @@ private function parseHeader() { * * @throws InvalidMessageDateException */ - public function parseRawHeader(string $raw_header){ + public function parseRawHeader(string $raw_header): void { $this->header = new Header($raw_header); } @@ -424,11 +550,11 @@ public function parseRawHeader(string $raw_header){ * Parse additional raw flags * @param array $raw_flags */ - public function parseRawFlags(array $raw_flags) { + public function parseRawFlags(array $raw_flags): void { $this->flags = FlagCollection::make([]); - foreach($raw_flags as $flag) { - if (strpos($flag, "\\") === 0){ + foreach ($raw_flags as $flag) { + if (str_starts_with($flag, "\\")) { $flag = substr($flag, 1); } $flag_key = strtolower($flag); @@ -442,17 +568,21 @@ public function parseRawFlags(array $raw_flags) { * Parse additional flags * * @return void - * @throws Exceptions\ConnectionFailedException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - private function parseFlags() { + private function parseFlags(): void { $this->client->openFolder($this->folder_path); $this->flags = FlagCollection::make([]); $sequence_id = $this->getSequenceId(); try { - $flags = $this->client->getConnection()->flags([$sequence_id], $this->sequence === IMAP::ST_UID); + $flags = $this->client->getConnection()->flags([$sequence_id], $this->sequence)->validatedData(); } catch (Exceptions\RuntimeException $e) { throw new MessageFlagException("flag could not be fetched", 0, $e); } @@ -465,20 +595,24 @@ private function parseFlags() { /** * Parse the Message body * - * @return $this - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\MessageContentFetchingException + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException - * @throws Exceptions\EventNotFoundException + * @throws MessageContentFetchingException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ public function parseBody(): Message { $this->client->openFolder($this->folder_path); $sequence_id = $this->getSequenceId(); try { - $contents = $this->client->getConnection()->content([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID); + $contents = $this->client->getConnection()->content([$sequence_id], "RFC822", $this->sequence)->validatedData(); } catch (Exceptions\RuntimeException $e) { throw new MessageContentFetchingException("failed to fetch content", 0); } @@ -493,20 +627,44 @@ public function parseBody(): Message { return $body; } + /** + * Fetches the size for this message. + * + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MessageSizeFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + private function fetchSize(): void { + $sequence_id = $this->getSequenceId(); + $sizes = $this->client->getConnection()->sizes([$sequence_id], $this->sequence)->validatedData(); + if (!isset($sizes[$sequence_id])) { + throw new MessageSizeFetchingException("sizes did not set an array entry for the supplied sequence_id", 0); + } + $this->attributes["size"] = $sizes[$sequence_id]; + } + /** * Handle auto "Seen" flag handling * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - public function peek(){ + public function peek(): void { if ($this->fetch_options == IMAP::FT_PEEK) { if ($this->getFlags()->get("seen") == null) { $this->unsetFlag("Seen"); } - }elseif ($this->getFlags()->get("seen") != null) { + } elseif ($this->getFlags()->get("seen") == null) { $this->setFlag("Seen"); } } @@ -515,11 +673,15 @@ public function peek(){ * Parse a given message body * @param string $raw_body * - * @return $this - * @throws Exceptions\ConnectionFailedException + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ public function parseRawBody(string $raw_body): Message { $this->structure = new Structure($raw_body, $this->header); @@ -532,11 +694,15 @@ public function parseRawBody(string $raw_body): Message { * Fetch the Message structure * @param Structure $structure * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - private function fetchStructure(Structure $structure) { - $this->client->openFolder($this->folder_path); + private function fetchStructure(Structure $structure): void { + $this->client?->openFolder($this->folder_path); foreach ($structure->parts as $part) { $this->fetchPart($part); @@ -547,10 +713,10 @@ private function fetchStructure(Structure $structure) { * Fetch a given part * @param Part $part */ - private function fetchPart(Part $part) { + private function fetchPart(Part $part): void { if ($part->isAttachment()) { $this->fetchAttachment($part); - }else{ + } else { $encoding = $this->getEncoding($part); $content = $this->decodeString($part->content, $part->encoding); @@ -570,14 +736,27 @@ private function fetchPart(Part $part) { $content = $this->convertEncoding($content, $encoding); } - $subtype = strtolower($part->subtype ?? ''); - $subtype = $subtype == "plain" || $subtype == "" ? "text" : $subtype; + $this->addBody($part->subtype ?? '', $content); + } + } - if (isset($this->bodies[$subtype])) { + /** + * Add a body to the message + * @param string $subtype + * @param string $content + * + * @return void + */ + protected function addBody(string $subtype, string $content): void { + $subtype = strtolower($subtype); + $subtype = $subtype == "plain" || $subtype == "" ? "text" : $subtype; + + if (isset($this->bodies[$subtype]) && $this->bodies[$subtype] !== null && $this->bodies[$subtype] !== "") { + if ($content !== "") { $this->bodies[$subtype] .= "\n".$content; - }else{ - $this->bodies[$subtype] = $content; } + } else { + $this->bodies[$subtype] = $content; } } @@ -585,11 +764,11 @@ private function fetchPart(Part $part) { * Fetch the Message attachment * @param Part $part */ - protected function fetchAttachment(Part $part) { + protected function fetchAttachment(Part $part): void { $oAttachment = new Attachment($this, $part); - if ($oAttachment->getName() !== null && $oAttachment->getSize() > 0) { - if ($oAttachment->getId() !== null) { + if ($oAttachment->getSize() > 0) { + if ($oAttachment->getId() !== null && $this->attachments->offsetExists($oAttachment->getId())) { $this->attachments->put($oAttachment->getId(), $oAttachment); } else { $this->attachments->push($oAttachment); @@ -601,7 +780,7 @@ protected function fetchAttachment(Part $part) { * Fail proof setter for $fetch_option * @param $option * - * @return $this + * @return Message */ public function setFetchOption($option): Message { if (is_long($option) === true) { @@ -618,9 +797,9 @@ public function setFetchOption($option): Message { * Set the sequence type * @param int|null $sequence * - * @return $this + * @return Message */ - public function setSequence($sequence): Message { + public function setSequence(?int $sequence): Message { if (is_long($sequence)) { $this->sequence = $sequence; } elseif (is_null($sequence)) { @@ -635,7 +814,7 @@ public function setSequence($sequence): Message { * Fail proof setter for $fetch_body * @param $option * - * @return $this + * @return Message */ public function setFetchBodyOption($option): Message { if (is_bool($option)) { @@ -652,7 +831,7 @@ public function setFetchBodyOption($option): Message { * Fail proof setter for $fetch_flags * @param $option * - * @return $this + * @return Message */ public function setFetchFlagsOption($option): Message { if (is_bool($option)) { @@ -699,7 +878,7 @@ public function decodeString($string, $encoding): string { * * @return mixed|string */ - public function convertEncoding($str, string $from = "ISO-8859-2", string $to = "UTF-8") { + public function convertEncoding($str, string $from = "ISO-8859-2", string $to = "UTF-8"): mixed { $from = EncodingAliases::get($from); $to = EncodingAliases::get($to); @@ -723,8 +902,12 @@ public function convertEncoding($str, string $from = "ISO-8859-2", string $to = return $str; } - if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') { - return @iconv($from, $to.'//IGNORE', $str); + if (function_exists('iconv') && !EncodingAliases::isUtf7($from) && !EncodingAliases::isUtf7($to)) { + try { + return iconv($from, $to.'//IGNORE', $str); + } catch (\Exception $e) { + return @iconv($from, $to, $str); + } } else { if (!$from) { return mb_convert_encoding($str, $to); @@ -735,21 +918,21 @@ public function convertEncoding($str, string $from = "ISO-8859-2", string $to = /** * Get the encoding of a given abject - * @param string|object $structure + * @param object|string $structure * - * @return string|null + * @return string */ - public function getEncoding($structure): string { + public function getEncoding(object|string $structure): string { if (property_exists($structure, 'parameters')) { foreach ($structure->parameters as $parameter) { if (strtolower($parameter->attribute) == "charset") { return EncodingAliases::get($parameter->value, "ISO-8859-2"); } } - }elseif (property_exists($structure, 'charset')){ + } elseif (property_exists($structure, 'charset')) { return EncodingAliases::get($structure->charset, "ISO-8859-2"); - }elseif (is_string($structure) === true){ - return mb_detect_encoding($structure); + } elseif (is_string($structure) === true) { + return EncodingAliases::detectEncoding($structure); } return 'UTF-8'; @@ -758,12 +941,16 @@ public function getEncoding($structure): string { /** * Get the messages folder * - * @return mixed - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\RuntimeException + * @return ?Folder + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - public function getFolder(){ + public function getFolder(): ?Folder { return $this->client->getFolderByPath($this->folder_path); } @@ -773,19 +960,23 @@ public function getFolder(){ * @param MessageCollection|null $thread * @param Folder|null $folder * - * @return MessageCollection|null - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\GetMessagesFailedException - * @throws Exceptions\RuntimeException + * @return MessageCollection + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function thread(Folder $sent_folder = null, MessageCollection &$thread = null, Folder $folder = null): MessageCollection { $thread = $thread ?: MessageCollection::make([]); - $folder = $folder ?: $this->getFolder(); + $folder = $folder ?: $this->getFolder(); $sent_folder = $sent_folder ?: $this->client->getFolderByPath(ClientManager::get("options.common_folders.sent", "INBOX/Sent")); /** @var Message $message */ - foreach($thread as $message) { + foreach ($thread as $message) { if ($message->message_id->first() == $this->message_id->first()) { return $thread; } @@ -795,11 +986,9 @@ public function thread(Folder $sent_folder = null, MessageCollection &$thread = $this->fetchThreadByInReplyTo($thread, $this->message_id, $folder, $folder, $sent_folder); $this->fetchThreadByInReplyTo($thread, $this->message_id, $sent_folder, $folder, $sent_folder); - if (is_array($this->in_reply_to)) { - foreach($this->in_reply_to as $in_reply_to) { - $this->fetchThreadByMessageId($thread, $in_reply_to, $folder, $folder, $sent_folder); - $this->fetchThreadByMessageId($thread, $in_reply_to, $sent_folder, $folder, $sent_folder); - } + foreach ($this->in_reply_to->all() as $in_reply_to) { + $this->fetchThreadByMessageId($thread, $in_reply_to, $folder, $folder, $sent_folder); + $this->fetchThreadByMessageId($thread, $in_reply_to, $sent_folder, $folder, $sent_folder); } return $thread; @@ -813,18 +1002,22 @@ public function thread(Folder $sent_folder = null, MessageCollection &$thread = * @param Folder $secondary_folder * @param Folder $sent_folder * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\GetMessagesFailedException - * @throws Exceptions\RuntimeException - * @throws Exceptions\FolderFetchingException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - protected function fetchThreadByInReplyTo(MessageCollection &$thread, string $in_reply_to, Folder $primary_folder, Folder $secondary_folder, Folder $sent_folder){ + protected function fetchThreadByInReplyTo(MessageCollection &$thread, string $in_reply_to, Folder $primary_folder, Folder $secondary_folder, Folder $sent_folder): void { $primary_folder->query()->inReplyTo($in_reply_to) - ->setFetchBody($this->getFetchBodyOption()) - ->leaveUnread()->get()->each(function($message) use(&$thread, $secondary_folder, $sent_folder){ - /** @var Message $message */ - $message->thread($sent_folder, $thread, $secondary_folder); - }); + ->setFetchBody($this->getFetchBodyOption()) + ->leaveUnread()->get()->each(function($message) use (&$thread, $secondary_folder, $sent_folder) { + /** @var Message $message */ + $message->thread($sent_folder, $thread, $secondary_folder); + }); } /** @@ -835,18 +1028,22 @@ protected function fetchThreadByInReplyTo(MessageCollection &$thread, string $in * @param Folder $secondary_folder * @param Folder $sent_folder * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\GetMessagesFailedException - * @throws Exceptions\RuntimeException - * @throws Exceptions\FolderFetchingException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws GetMessagesFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ - protected function fetchThreadByMessageId(MessageCollection &$thread, string $message_id, Folder $primary_folder, Folder $secondary_folder, Folder $sent_folder){ + protected function fetchThreadByMessageId(MessageCollection &$thread, string $message_id, Folder $primary_folder, Folder $secondary_folder, Folder $sent_folder): void { $primary_folder->query()->messageId($message_id) - ->setFetchBody($this->getFetchBodyOption()) - ->leaveUnread()->get()->each(function($message) use(&$thread, $secondary_folder, $sent_folder){ - /** @var Message $message */ - $message->thread($sent_folder, $thread, $secondary_folder); - }); + ->setFetchBody($this->getFetchBodyOption()) + ->leaveUnread()->get()->each(function($message) use (&$thread, $secondary_folder, $sent_folder) { + /** @var Message $message */ + $message->thread($sent_folder, $thread, $secondary_folder); + }); } /** @@ -855,28 +1052,35 @@ protected function fetchThreadByMessageId(MessageCollection &$thread, string $me * @param boolean $expunge * * @return null|Message - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException - * @throws MessageHeaderFetchingException - * @throws Exceptions\EventNotFoundException * @throws MessageFlagException - * @throws Exceptions\MessageNotFoundException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ - public function copy(string $folder_path, bool $expunge = false) { + public function copy(string $folder_path, bool $expunge = false): ?Message { $this->client->openFolder($folder_path); - $status = $this->client->getConnection()->examineFolder($folder_path); + $status = $this->client->getConnection()->examineFolder($folder_path)->validatedData(); if (isset($status["uidnext"])) { $next_uid = $status["uidnext"]; + if ((int)$next_uid <= 0) { + return null; + } /** @var Folder $folder */ $folder = $this->client->getFolderByPath($folder_path); $this->client->openFolder($this->folder_path); - if ($this->client->getConnection()->copyMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) { + if ($this->client->getConnection()->copyMessage($folder->path, $this->getSequenceId(), null, $this->sequence)->validatedData()) { return $this->fetchNewMail($folder, $next_uid, "copied", $expunge); } } @@ -890,28 +1094,35 @@ public function copy(string $folder_path, bool $expunge = false) { * @param boolean $expunge * * @return Message|null - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException - * @throws MessageHeaderFetchingException - * @throws Exceptions\EventNotFoundException * @throws MessageFlagException - * @throws Exceptions\MessageNotFoundException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ - public function move(string $folder_path, bool $expunge = false) { + public function move(string $folder_path, bool $expunge = false): ?Message { $this->client->openFolder($folder_path); - $status = $this->client->getConnection()->examineFolder($folder_path); + $status = $this->client->getConnection()->examineFolder($folder_path)->validatedData(); if (isset($status["uidnext"])) { $next_uid = $status["uidnext"]; + if ((int)$next_uid <= 0) { + return null; + } /** @var Folder $folder */ $folder = $this->client->getFolderByPath($folder_path); $this->client->openFolder($this->folder_path); - if ($this->client->getConnection()->moveMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) { + if ($this->client->getConnection()->moveMessage($folder->path, $this->getSequenceId(), null, $this->sequence)->validatedData()) { return $this->fetchNewMail($folder, $next_uid, "moved", $expunge); } } @@ -927,24 +1138,28 @@ public function move(string $folder_path, bool $expunge = false) { * @param boolean $expunge * * @return Message - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException * @throws MessageFlagException * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ protected function fetchNewMail(Folder $folder, int $next_uid, string $event, bool $expunge): Message { - if($expunge) $this->client->expunge(); + if ($expunge) $this->client->expunge(); $this->client->openFolder($folder->path); if ($this->sequence === IMAP::ST_UID) { $sequence_id = $next_uid; - }else{ - $sequence_id = $this->client->getConnection()->getMessageNumber($next_uid); + } else { + $sequence_id = $this->client->getConnection()->getMessageNumber($next_uid)->validatedData(); } $message = $folder->query()->getMessage($sequence_id, null, $this->sequence); @@ -961,23 +1176,27 @@ protected function fetchNewMail(Folder $folder, int $next_uid, string $event, bo * @param boolean $force_move * * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\FolderFetchingException - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\RuntimeException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException * @throws MessageFlagException * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ - public function delete(bool $expunge = true, string $trash_path = null, bool $force_move = false) { + public function delete(bool $expunge = true, string $trash_path = null, bool $force_move = false): bool { $status = $this->setFlag("Deleted"); - if($force_move) { - $trash_path = $trash_path === null ? $this->config["common_folders"]["trash"]: $trash_path; - $status = $this->move($trash_path); + if ($force_move) { + $trash_path = $trash_path === null ? $this->config["common_folders"]["trash"] : $trash_path; + $this->move($trash_path); } - if($expunge) $this->client->expunge(); + if ($expunge) $this->client->expunge(); $event = $this->getEvent("message", "deleted"); $event::dispatch($this); @@ -990,14 +1209,18 @@ public function delete(bool $expunge = true, string $trash_path = null, bool $fo * @param boolean $expunge * * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ public function restore(bool $expunge = true): bool { $status = $this->unsetFlag("Deleted"); - if($expunge) $this->client->expunge(); + if ($expunge) $this->client->expunge(); $event = $this->getEvent("message", "restored"); $event::dispatch($this); @@ -1007,20 +1230,24 @@ public function restore(bool $expunge = true): bool { /** * Set a given flag - * @param string|array $flag + * @param array|string $flag * * @return bool - * @throws Exceptions\ConnectionFailedException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - public function setFlag($flag): bool { + public function setFlag(array|string $flag): bool { $this->client->openFolder($this->folder_path); - $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag); + $flag = "\\" . trim(is_array($flag) ? implode(" \\", $flag) : $flag); $sequence_id = $this->getSequenceId(); try { - $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "+", true, $this->sequence === IMAP::ST_UID); + $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "+", true, $this->sequence)->validatedData(); } catch (Exceptions\RuntimeException $e) { throw new MessageFlagException("flag could not be set", 0, $e); } @@ -1034,21 +1261,25 @@ public function setFlag($flag): bool { /** * Unset a given flag - * @param string|array $flag + * @param array|string $flag * * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - public function unsetFlag($flag): bool { + public function unsetFlag(array|string $flag): bool { $this->client->openFolder($this->folder_path); - $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag); + $flag = "\\" . trim(is_array($flag) ? implode(" \\", $flag) : $flag); $sequence_id = $this->getSequenceId(); try { - $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "-", true, $this->sequence === IMAP::ST_UID); + $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "-", true, $this->sequence)->validatedData(); } catch (Exceptions\RuntimeException $e) { throw new MessageFlagException("flag could not be removed", 0, $e); } @@ -1062,29 +1293,37 @@ public function unsetFlag($flag): bool { /** * Set a given flag - * @param string|array $flag + * @param array|string $flag * * @return bool - * @throws Exceptions\ConnectionFailedException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\EventNotFoundException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - public function addFlag($flag): bool { + public function addFlag(array|string $flag): bool { return $this->setFlag($flag); } /** * Unset a given flag - * @param string|array $flag + * @param array|string $flag * * @return bool - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\EventNotFoundException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageFlagException - * @throws Exceptions\RuntimeException + * @throws RuntimeException + * @throws ResponseException */ - public function removeFlag($flag): bool { + public function removeFlag(array|string $flag): bool { return $this->unsetFlag($flag); } @@ -1119,13 +1358,9 @@ public function hasAttachments(): bool { * Get the raw body * * @return string - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\RuntimeException */ - public function getRawBody() { - if ($this->raw_body === null) { - $this->client->openFolder($this->folder_path); - + public function getRawBody(): string { + if ($this->raw_body === "") { $this->raw_body = $this->structure->raw; } @@ -1135,27 +1370,27 @@ public function getRawBody() { /** * Get the message header * - * @return Header + * @return ?Header */ - public function getHeader() { + public function getHeader(): ?Header { return $this->header; } /** * Get the current client * - * @return Client + * @return ?Client */ - public function getClient(): Client { + public function getClient(): ?Client { return $this->client; } /** * Get the used fetch option * - * @return integer + * @return ?integer */ - public function getFetchOptions() { + public function getFetchOptions(): ?int { return $this->fetch_options; } @@ -1164,7 +1399,7 @@ public function getFetchOptions() { * * @return boolean */ - public function getFetchBodyOption() { + public function getFetchBodyOption(): bool { return $this->fetch_body; } @@ -1173,7 +1408,7 @@ public function getFetchBodyOption() { * * @return boolean */ - public function getFetchFlagsOption() { + public function getFetchFlagsOption(): bool { return $this->fetch_flags; } @@ -1204,19 +1439,30 @@ public function flags(): FlagCollection { return $this->getFlags(); } + /** + * Check if a flag is set + * + * @param string $flag + * @return boolean + */ + public function hasFlag(string $flag): bool { + $flag = str_replace("\\", "", strtolower($flag)); + return $this->getFlags()->has($flag); + } + /** * Get the fetched structure * * @return Structure|null */ - public function getStructure(){ + public function getStructure(): ?Structure { return $this->structure; } /** - * Check if a message matches an other by comparing basic attributes + * Check if a message matches another by comparing basic attributes * - * @param null|Message $message + * @param null|Message $message * @return boolean */ public function is(Message $message = null): bool { @@ -1227,7 +1473,7 @@ public function is(Message $message = null): bool { return $this->uid == $message->uid && $this->message_id->first() == $message->message_id->first() && $this->subject->first() == $message->subject->first() - && $this->date->toDate()->eq($message->date); + && $this->date->toDate()->eq($message->date->toDate()); } /** @@ -1243,10 +1489,10 @@ public function getAttributes(): array { * Set the message mask * @param $mask * - * @return $this + * @return Message */ public function setMask($mask): Message { - if(class_exists($mask)){ + if (class_exists($mask)) { $this->mask = $mask; } @@ -1264,18 +1510,18 @@ public function getMask(): string { /** * Get a masked instance by providing a mask name - * @param string|mixed $mask + * @param mixed|null $mask * * @return mixed * @throws MaskNotFoundException */ - public function mask($mask = null){ + public function mask(mixed $mask = null): mixed { $mask = $mask !== null ? $mask : $this->mask; - if(class_exists($mask)){ + if (class_exists($mask)) { return new $mask($this); } - throw new MaskNotFoundException("Unknown mask provided: ".$mask); + throw new MaskNotFoundException("Unknown mask provided: " . $mask); } /** @@ -1291,7 +1537,7 @@ public function getFolderPath(): string { * Set the message path aka folder path * @param $folder_path * - * @return $this + * @return Message */ public function setFolderPath($folder_path): Message { $this->folder_path = $folder_path; @@ -1301,21 +1547,30 @@ public function setFolderPath($folder_path): Message { /** * Set the config - * @param $config + * @param array $config * - * @return $this + * @return Message */ - public function setConfig($config): Message { + public function setConfig(array $config): Message { $this->config = $config; return $this; } + /** + * Get the config + * + * @return array + */ + public function getConfig(): array { + return $this->config; + } + /** * Set the available flags * @param $available_flags * - * @return $this + * @return Message */ public function setAvailableFlags($available_flags): Message { $this->available_flags = $available_flags; @@ -1323,11 +1578,20 @@ public function setAvailableFlags($available_flags): Message { return $this; } + /** + * Get the available flags + * + * @return array + */ + public function getAvailableFlags(): array { + return $this->available_flags; + } + /** * Set the attachment collection * @param $attachments * - * @return $this + * @return Message */ public function setAttachments($attachments): Message { $this->attachments = $attachments; @@ -1339,7 +1603,7 @@ public function setAttachments($attachments): Message { * Set the flag collection * @param $flags * - * @return $this + * @return Message */ public function setFlags($flags): Message { $this->flags = $flags; @@ -1351,13 +1615,17 @@ public function setFlags($flags): Message { * Set the client * @param $client * - * @return $this - * @throws Exceptions\RuntimeException - * @throws Exceptions\ConnectionFailedException + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function setClient($client): Message { $this->client = $client; - $this->client->openFolder($this->folder_path); + $this->client?->openFolder($this->folder_path); return $this; } @@ -1366,13 +1634,11 @@ public function setClient($client): Message { * Set the message number * @param int $uid * - * @return $this - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\ConnectionFailedException + * @return Message */ public function setUid(int $uid): Message { $this->uid = $uid; - $this->msgn = $this->client->getConnection()->getMessageNumber($this->uid); + $this->msgn = null; $this->msglist = null; return $this; @@ -1383,14 +1649,12 @@ public function setUid(int $uid): Message { * @param int $msgn * @param int|null $msglist * - * @return $this - * @throws Exceptions\MessageNotFoundException - * @throws Exceptions\ConnectionFailedException + * @return Message */ public function setMsgn(int $msgn, int $msglist = null): Message { $this->msgn = $msgn; $this->msglist = $msglist; - $this->uid = $this->client->getConnection()->getUid($this->msgn); + $this->uid = null; return $this; } @@ -1405,7 +1669,7 @@ public function getSequence(): int { } /** - * Set the sequence type + * Get the current sequence id (either a UID or a message number!) * * @return int */ @@ -1417,16 +1681,23 @@ public function getSequenceId(): int { * Set the sequence id * @param $uid * @param int|null $msglist - * - * @throws Exceptions\ConnectionFailedException - * @throws Exceptions\MessageNotFoundException */ - public function setSequenceId($uid, int $msglist = null){ + public function setSequenceId($uid, int $msglist = null): void { if ($this->getSequence() === IMAP::ST_UID) { $this->setUid($uid); $this->setMsglist($msglist); - }else{ + } else { $this->setMsgn($uid, $msglist); } } + + /** + * Safe the entire message in a file + * @param $filename + * + * @return bool|int + */ + public function save($filename): bool|int { + return file_put_contents($filename, $this->header->raw."\r\n\r\n".$this->structure->raw); + } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Part.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Part.php index f29b63485..1759b8de1 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Part.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Part.php @@ -27,117 +27,117 @@ class Part { * * @var string $raw */ - public $raw = ""; + public string $raw = ""; /** * Part type * * @var int $type */ - public $type = IMAP::MESSAGE_TYPE_TEXT; + public int $type = IMAP::MESSAGE_TYPE_TEXT; /** * Part content * * @var string $content */ - public $content = ""; + public string $content = ""; /** * Part subtype * - * @var string $subtype + * @var ?string $subtype */ - public $subtype = null; + public ?string $subtype = null; /** * Part charset - if available * * @var string $charset */ - public $charset = "utf-8"; + public string $charset = "utf-8"; /** * Part encoding method * * @var int $encoding */ - public $encoding = IMAP::MESSAGE_ENC_OTHER; + public int $encoding = IMAP::MESSAGE_ENC_OTHER; /** * Alias to check if the part is an attachment * * @var boolean $ifdisposition */ - public $ifdisposition = false; + public bool $ifdisposition = false; /** * Indicates if the part is an attachment * - * @var string $disposition + * @var ?string $disposition */ - public $disposition = null; + public ?string $disposition = null; /** * Alias to check if the part has a description * * @var boolean $ifdescription */ - public $ifdescription = false; + public bool $ifdescription = false; /** * Part description if available * - * @var string $description + * @var ?string $description */ - public $description = null; + public ?string $description = null; /** * Part filename if available * - * @var string $filename + * @var ?string $filename */ - public $filename = null; + public ?string $filename = null; /** * Part name if available * - * @var string $name + * @var ?string $name */ - public $name = null; + public ?string $name = null; /** * Part id if available * - * @var string $id + * @var ?string $id */ - public $id = null; + public ?string $id = null; /** * The part number of the current part * * @var integer $part_number */ - public $part_number = 0; + public int $part_number = 0; /** * Part length in bytes * * @var integer $bytes */ - public $bytes = null; + public int $bytes; /** * Part content type * * @var string|null $content_type */ - public $content_type = null; + public ?string $content_type = null; /** - * @var Header $header + * @var ?Header $header */ - private $header = null; + private ?Header $header; /** * Part constructor. @@ -159,7 +159,7 @@ public function __construct($raw_part, Header $header = null, int $part_number = * * @throws InvalidMessageDateException */ - protected function parse(){ + protected function parse(): void { if ($this->header === null) { $body = $this->findHeaders(); }else{ @@ -170,33 +170,29 @@ protected function parse(){ $this->parseDescription(); $this->parseEncoding(); - $this->charset = $this->header->get("charset"); + $this->charset = $this->header->get("charset")->first(); $this->name = $this->header->get("name"); $this->filename = $this->header->get("filename"); - if(!empty($this->header->get("id"))) { + if($this->header->get("id")->exist()) { $this->id = $this->header->get("id"); - } else if(!empty($this->header->get("x_attachment_id"))){ + } else if($this->header->get("x_attachment_id")->exist()){ $this->id = $this->header->get("x_attachment_id"); - } else if(!empty($this->header->get("content_id"))){ + } else if($this->header->get("content_id")->exist()){ $this->id = strtr($this->header->get("content_id"), [ '<' => '', '>' => '' ]); } - $content_types = $this->header->get("content_type"); + $content_types = $this->header->get("content_type")->all(); if(!empty($content_types)){ $this->subtype = $this->parseSubtype($content_types); - $content_type = $content_types; - if (is_array($content_types)) { - $content_type = $content_types[0]; - } + $content_type = $content_types[0]; $parts = explode(';', $content_type); $this->content_type = trim($parts[0]); } - $this->content = trim(rtrim($body)); $this->bytes = strlen($this->content); } @@ -224,9 +220,9 @@ private function findHeaders(): string { * Try to parse the subtype if any is present * @param $content_type * - * @return string + * @return ?string */ - private function parseSubtype($content_type){ + private function parseSubtype($content_type): ?string { if (is_array($content_type)) { foreach ($content_type as $part){ if ((strpos($part, "/")) !== false){ @@ -236,7 +232,7 @@ private function parseSubtype($content_type){ return null; } if (($pos = strpos($content_type, "/")) !== false){ - return substr($content_type, $pos + 1); + return substr(explode(";", $content_type)[0], $pos + 1); } return null; } @@ -244,20 +240,20 @@ private function parseSubtype($content_type){ /** * Try to parse the disposition if any is present */ - private function parseDisposition(){ - $content_disposition = $this->header->get("content_disposition"); - if($content_disposition !== null) { + private function parseDisposition(): void { + $content_disposition = $this->header->get("content_disposition")->first(); + if($content_disposition) { $this->ifdisposition = true; - $this->disposition = (is_array($content_disposition)) ? implode(' ', $content_disposition) : $content_disposition; + $this->disposition = (is_array($content_disposition)) ? implode(' ', $content_disposition) : explode(";", $content_disposition)[0]; } } /** * Try to parse the description if any is present */ - private function parseDescription(){ - $content_description = $this->header->get("content_description"); - if($content_description !== null) { + private function parseDescription(): void { + $content_description = $this->header->get("content_description")->first(); + if($content_description) { $this->ifdescription = true; $this->description = $content_description; } @@ -266,30 +262,17 @@ private function parseDescription(){ /** * Try to parse the encoding if any is present */ - private function parseEncoding(){ - $encoding = $this->header->get("content_transfer_encoding"); - if($encoding !== null) { - switch (strtolower($encoding)) { - case "quoted-printable": - $this->encoding = IMAP::MESSAGE_ENC_QUOTED_PRINTABLE; - break; - case "base64": - $this->encoding = IMAP::MESSAGE_ENC_BASE64; - break; - case "7bit": - $this->encoding = IMAP::MESSAGE_ENC_7BIT; - break; - case "8bit": - $this->encoding = IMAP::MESSAGE_ENC_8BIT; - break; - case "binary": - $this->encoding = IMAP::MESSAGE_ENC_BINARY; - break; - default: - $this->encoding = IMAP::MESSAGE_ENC_OTHER; - break; - - } + private function parseEncoding(): void { + $encoding = $this->header->get("content_transfer_encoding")->first(); + if($encoding) { + $this->encoding = match (strtolower($encoding)) { + "quoted-printable" => IMAP::MESSAGE_ENC_QUOTED_PRINTABLE, + "base64" => IMAP::MESSAGE_ENC_BASE64, + "7bit" => IMAP::MESSAGE_ENC_7BIT, + "8bit" => IMAP::MESSAGE_ENC_8BIT, + "binary" => IMAP::MESSAGE_ENC_BINARY, + default => IMAP::MESSAGE_ENC_OTHER, + }; } } @@ -306,7 +289,20 @@ public function isAttachment(): bool { return false; } } + + if ($this->disposition === "inline" && $this->filename == null && $this->name == null && !$this->header->has("content_id")) { + return false; + } return true; } + /** + * Get the part header + * + * @return Header|null + */ + public function getHeader(): ?Header { + return $this->header; + } + } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/Query.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/Query.php index 361a1ceff..727e641f0 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/Query.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/Query.php @@ -19,15 +19,19 @@ use ReflectionException; use Webklex\PHPIMAP\Client; use Webklex\PHPIMAP\ClientManager; +use Webklex\PHPIMAP\Exceptions\AuthFailedException; use Webklex\PHPIMAP\Exceptions\ConnectionFailedException; use Webklex\PHPIMAP\Exceptions\EventNotFoundException; use Webklex\PHPIMAP\Exceptions\GetMessagesFailedException; +use Webklex\PHPIMAP\Exceptions\ImapBadRequestException; +use Webklex\PHPIMAP\Exceptions\ImapServerErrorException; use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException; use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException; use Webklex\PHPIMAP\Exceptions\MessageFlagException; use Webklex\PHPIMAP\Exceptions\MessageHeaderFetchingException; use Webklex\PHPIMAP\Exceptions\MessageNotFoundException; use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException; +use Webklex\PHPIMAP\Exceptions\ResponseException; use Webklex\PHPIMAP\Exceptions\RuntimeException; use Webklex\PHPIMAP\IMAP; use Webklex\PHPIMAP\Message; @@ -41,46 +45,46 @@ class Query { /** @var Collection $query */ - protected $query; + protected Collection $query; /** @var string $raw_query */ - protected $raw_query; + protected string $raw_query; /** @var string[] $extensions */ - protected $extensions; + protected array $extensions; /** @var Client $client */ - protected $client; + protected Client $client; - /** @var int $limit */ - protected $limit = null; + /** @var ?int $limit */ + protected ?int $limit = null; /** @var int $page */ - protected $page = 1; + protected int $page = 1; - /** @var int $fetch_options */ - protected $fetch_options = null; + /** @var ?int $fetch_options */ + protected ?int $fetch_options = null; - /** @var int $fetch_body */ - protected $fetch_body = true; + /** @var boolean $fetch_body */ + protected bool $fetch_body = true; - /** @var int $fetch_flags */ - protected $fetch_flags = true; + /** @var boolean $fetch_flags */ + protected bool $fetch_flags = true; /** @var int|string $sequence */ - protected $sequence = IMAP::NIL; + protected mixed $sequence = IMAP::NIL; /** @var string $fetch_order */ - protected $fetch_order; + protected string $fetch_order; /** @var string $date_format */ - protected $date_format; + protected string $date_format; /** @var bool $soft_fail */ - protected $soft_fail = false; + protected bool $soft_fail = false; /** @var array $errors */ - protected $errors = []; + protected array $errors = []; /** * Query constructor. @@ -110,7 +114,7 @@ public function __construct(Client $client, array $extensions = []) { /** * Instance boot method for additional functionality */ - protected function boot() { + protected function boot(): void { } /** @@ -119,7 +123,7 @@ protected function boot() { * * @return string */ - protected function parse_value($value): string { + protected function parse_value(mixed $value): string { if ($value instanceof Carbon) { $value = $value->format($this->date_format); } @@ -129,17 +133,17 @@ protected function parse_value($value): string { /** * Check if a given date is a valid carbon object and if not try to convert it - * @param string|Carbon $date + * @param mixed $date * * @return Carbon * @throws MessageSearchValidationException */ - protected function parse_date($date): Carbon { + protected function parse_date(mixed $date): Carbon { if ($date instanceof Carbon) return $date; try { $date = Carbon::parse($date); - } catch (Exception $e) { + } catch (Exception) { throw new MessageSearchValidationException(); } @@ -181,16 +185,18 @@ public function generate_query(): string { * * @return Collection * @throws GetMessagesFailedException + * @throws AuthFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException */ protected function search(): Collection { $this->generate_query(); try { - $available_messages = $this->client->getConnection()->search([$this->getRawQuery()], $this->sequence); + $available_messages = $this->client->getConnection()->search([$this->getRawQuery()], $this->sequence)->validatedData(); return new Collection($available_messages); - } catch (RuntimeException $e) { - throw new GetMessagesFailedException("failed to fetch messages", 0, $e); - } catch (ConnectionFailedException $e) { + } catch (RuntimeException|ConnectionFailedException $e) { throw new GetMessagesFailedException("failed to fetch messages", 0, $e); } } @@ -199,7 +205,11 @@ protected function search(): Collection { * Count all available messages matching the current search criteria * * @return int + * @throws AuthFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException */ public function count(): int { return $this->search()->count(); @@ -210,8 +220,12 @@ public function count(): int { * @param Collection $available_messages * * @return array + * @throws AuthFailedException * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws RuntimeException + * @throws ResponseException */ protected function fetch(Collection $available_messages): array { if ($this->fetch_order === 'desc') { @@ -221,14 +235,14 @@ protected function fetch(Collection $available_messages): array { $uids = $available_messages->forPage($this->page, $this->limit)->toArray(); $extensions = $this->getExtensions(); if (empty($extensions) === false && method_exists($this->client->getConnection(), "fetch")) { - $extensions = $this->client->getConnection()->fetch($extensions, $uids, null, $this->sequence); + $extensions = $this->client->getConnection()->fetch($extensions, $uids, null, $this->sequence)->validatedData(); } - $flags = $this->client->getConnection()->flags($uids, $this->sequence); - $headers = $this->client->getConnection()->headers($uids, "RFC822", $this->sequence); + $flags = $this->client->getConnection()->flags($uids, $this->sequence)->validatedData(); + $headers = $this->client->getConnection()->headers($uids, "RFC822", $this->sequence)->validatedData(); $contents = []; if ($this->getFetchBody()) { - $contents = $this->client->getConnection()->content($uids, "RFC822", $this->sequence); + $contents = $this->client->getConnection()->content($uids, "RFC822", $this->sequence)->validatedData(); } return [ @@ -249,23 +263,19 @@ protected function fetch(Collection $available_messages): array { * @param array $flags * * @return Message|null + * @throws AuthFailedException * @throws ConnectionFailedException * @throws EventNotFoundException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws ReflectionException + * @throws ResponseException */ - protected function make(int $uid, int $msglist, string $header, string $content, array $flags) { + protected function make(int $uid, int $msglist, string $header, string $content, array $flags): ?Message { try { return Message::make($uid, $msglist, $this->getClient(), $header, $content, $flags, $this->getFetchOptions(), $this->sequence); - } catch (MessageNotFoundException $e) { - $this->setError($uid, $e); - } catch (RuntimeException $e) { - $this->setError($uid, $e); - } catch (MessageFlagException $e) { - $this->setError($uid, $e); - } catch (InvalidMessageDateException $e) { - $this->setError($uid, $e); - } catch (MessageContentFetchingException $e) { + } catch (RuntimeException|MessageFlagException|InvalidMessageDateException|MessageContentFetchingException $e) { $this->setError($uid, $e); } @@ -283,20 +293,12 @@ protected function make(int $uid, int $msglist, string $header, string $content, * @return string */ protected function getMessageKey(string $message_key, int $msglist, Message $message): string { - switch ($message_key) { - case 'number': - $key = $message->getMessageNo(); - break; - case 'list': - $key = $msglist; - break; - case 'uid': - $key = $message->getUid(); - break; - default: - $key = $message->getMessageId(); - break; - } + $key = match ($message_key) { + 'number' => $message->getMessageNo(), + 'list' => $msglist, + 'uid' => $message->getUid(), + default => $message->getMessageId(), + }; return (string)$key; } @@ -323,11 +325,15 @@ public function curate_messages(Collection $available_messages): MessageCollecti * @param Collection $available_messages * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws EventNotFoundException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws ReflectionException * @throws RuntimeException + * @throws ResponseException */ protected function populate(Collection $available_messages): MessageCollection { $messages = MessageCollection::make([]); @@ -345,7 +351,7 @@ protected function populate(Collection $available_messages): MessageCollection { $extensions = $raw_messages["extensions"][$uid] ?? []; $message = $this->make($uid, $msglist, $header, $content, $flag); - foreach($extensions as $key => $extension) { + foreach ($extensions as $key => $extension) { $message->getHeader()->set($key, $extension); } if ($message !== null) { @@ -362,7 +368,11 @@ protected function populate(Collection $available_messages): MessageCollection { * Fetch the current query and return all found messages * * @return MessageCollection + * @throws AuthFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException */ public function get(): MessageCollection { return $this->curate_messages($this->search()); @@ -374,13 +384,17 @@ public function get(): MessageCollection { * @param int $chunk_size * @param int $start_chunk * + * @throws AuthFailedException * @throws ConnectionFailedException * @throws EventNotFoundException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws ReflectionException * @throws RuntimeException + * @throws ResponseException */ - public function chunked(callable $callback, int $chunk_size = 10, int $start_chunk = 1) { + public function chunked(callable $callback, int $chunk_size = 10, int $start_chunk = 1): void { $available_messages = $this->search(); if (($available_messages_count = $available_messages->count()) > 0) { $old_limit = $this->limit; @@ -403,21 +417,21 @@ public function chunked(callable $callback, int $chunk_size = 10, int $start_chu /** * Paginate the current query * @param int $per_page Results you which to receive per page - * @param int|null $page The current page you are on (e.g. 0, 1, 2, ...) use `null` to enable auto mode + * @param null $page The current page you are on (e.g. 0, 1, 2, ...) use `null` to enable auto mode * @param string $page_name The page name / uri parameter used for the generated links and the auto mode * * @return LengthAwarePaginator + * @throws AuthFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException */ public function paginate(int $per_page = 5, $page = null, string $page_name = 'imap_page'): LengthAwarePaginator { - if ( - $page === null - && isset($_GET[$page_name]) - && $_GET[$page_name] > 0 - ) { + if ($page === null && isset($_GET[$page_name]) && $_GET[$page_name] > 0) { $this->page = intval($_GET[$page_name]); } elseif ($page > 0) { - $this->page = $page; + $this->page = (int)$page; } $this->limit = $per_page; @@ -428,37 +442,43 @@ public function paginate(int $per_page = 5, $page = null, string $page_name = 'i /** * Get a new Message instance * @param int $uid - * @param int|null $msglist - * @param int|string|null $sequence + * @param null $msglist + * @param null $sequence * * @return Message + * @throws AuthFailedException * @throws ConnectionFailedException - * @throws RuntimeException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException - * @throws MessageHeaderFetchingException - * @throws EventNotFoundException * @throws MessageFlagException - * @throws MessageNotFoundException + * @throws MessageHeaderFetchingException + * @throws RuntimeException + * @throws ResponseException */ public function getMessage(int $uid, $msglist = null, $sequence = null): Message { - return new Message($uid, $msglist, $this->getClient(), $this->getFetchOptions(), $this->getFetchBody(), $this->getFetchFlags(), $sequence ? $sequence : $this->sequence); + return new Message($uid, $msglist, $this->getClient(), $this->getFetchOptions(), $this->getFetchBody(), $this->getFetchFlags(), $sequence ?: $this->sequence); } /** * Get a message by its message number * @param $msgn - * @param int|null $msglist + * @param null $msglist * * @return Message + * @throws AuthFailedException * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException + * @throws MessageFlagException * @throws MessageHeaderFetchingException * @throws RuntimeException - * @throws EventNotFoundException - * @throws MessageFlagException - * @throws MessageNotFoundException + * @throws ResponseException */ public function getMessageByMsgn($msgn, $msglist = null): Message { return $this->getMessage($msgn, $msglist, IMAP::ST_MSGN); @@ -469,14 +489,17 @@ public function getMessageByMsgn($msgn, $msglist = null): Message { * @param $uid * * @return Message + * @throws AuthFailedException * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws InvalidMessageDateException * @throws MessageContentFetchingException + * @throws MessageFlagException * @throws MessageHeaderFetchingException * @throws RuntimeException - * @throws EventNotFoundException - * @throws MessageFlagException - * @throws MessageNotFoundException + * @throws ResponseException */ public function getMessageByUid($uid): Message { return $this->getMessage($uid, null, IMAP::ST_UID); @@ -487,17 +510,22 @@ public function getMessageByUid($uid): Message { * @param callable $closure * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function filter(callable $closure): MessageCollection { $connection = $this->getClient()->getConnection(); - $uids = $connection->getUid(); + $uids = $connection->getUid()->validatedData(); $available_messages = new Collection(); if (is_array($uids)) { - foreach ($uids as $id){ + foreach ($uids as $id) { if ($closure($id)) { $available_messages->push($id); } @@ -512,12 +540,17 @@ public function filter(callable $closure): MessageCollection { * @param int $uid * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function getByUidGreaterOrEqual(int $uid): MessageCollection { - return $this->filter(function($id) use($uid){ + return $this->filter(function($id) use ($uid) { return $id >= $uid; }); } @@ -527,12 +560,17 @@ public function getByUidGreaterOrEqual(int $uid): MessageCollection { * @param int $uid * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function getByUidGreater(int $uid): MessageCollection { - return $this->filter(function($id) use($uid){ + return $this->filter(function($id) use ($uid) { return $id > $uid; }); } @@ -542,12 +580,17 @@ public function getByUidGreater(int $uid): MessageCollection { * @param int $uid * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function getByUidLower(int $uid): MessageCollection { - return $this->filter(function($id) use($uid){ + return $this->filter(function($id) use ($uid) { return $id < $uid; }); } @@ -557,12 +600,17 @@ public function getByUidLower(int $uid): MessageCollection { * @param int $uid * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function getByUidLowerOrEqual(int $uid): MessageCollection { - return $this->filter(function($id) use($uid){ + return $this->filter(function($id) use ($uid) { return $id <= $uid; }); } @@ -572,12 +620,17 @@ public function getByUidLowerOrEqual(int $uid): MessageCollection { * @param int $uid * * @return MessageCollection + * @throws AuthFailedException * @throws ConnectionFailedException * @throws GetMessagesFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException * @throws MessageNotFoundException + * @throws RuntimeException + * @throws ResponseException */ public function getByUidLowerThan(int $uid): MessageCollection { - return $this->filter(function($id) use($uid){ + return $this->filter(function($id) use ($uid) { return $id < $uid; }); } @@ -621,13 +674,18 @@ public function setSequence(int $sequence): Query { * * @return int|string */ - public function getSequence() { + public function getSequence(): int|string { return $this->sequence; } /** * @return Client + * @throws AuthFailedException * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + * @throws ResponseException */ public function getClient(): Client { $this->client->checkConnection(); @@ -649,6 +707,8 @@ public function limit(int $limit, int $page = 1): Query { } /** + * Get the current query collection + * * @return Collection */ public function getQuery(): Collection { @@ -656,7 +716,9 @@ public function getQuery(): Collection { } /** + * Set all query parameters * @param array $query + * * @return Query */ public function setQuery(array $query): Query { @@ -665,6 +727,8 @@ public function setQuery(array $query): Query { } /** + * Get the raw query + * * @return string */ public function getRawQuery(): string { @@ -672,7 +736,9 @@ public function getRawQuery(): string { } /** + * Set the raw query * @param string $raw_query + * * @return Query */ public function setRawQuery(string $raw_query): Query { @@ -681,6 +747,8 @@ public function setRawQuery(string $raw_query): Query { } /** + * Get all applied extensions + * * @return string[] */ public function getExtensions(): array { @@ -688,7 +756,9 @@ public function getExtensions(): array { } /** + * Set all extensions that should be used * @param string[] $extensions + * * @return Query */ public function setExtensions(array $extensions): Query { @@ -702,7 +772,9 @@ public function setExtensions(array $extensions): Query { } /** + * Set the client instance * @param Client $client + * * @return Query */ public function setClient(Client $client): Query { @@ -712,14 +784,17 @@ public function setClient(Client $client): Query { /** * Get the set fetch limit - * @return int + * + * @return ?int */ - public function getLimit() { + public function getLimit(): ?int { return $this->limit; } /** + * Set the fetch limit * @param int $limit + * * @return Query */ public function setLimit(int $limit): Query { @@ -728,6 +803,8 @@ public function setLimit(int $limit): Query { } /** + * Get the set page + * * @return int */ public function getPage(): int { @@ -735,7 +812,9 @@ public function getPage(): int { } /** + * Set the page * @param int $page + * * @return Query */ public function setPage(int $page): Query { @@ -744,7 +823,9 @@ public function setPage(int $page): Query { } /** + * Set the fetch option flag * @param int $fetch_options + * * @return Query */ public function setFetchOptions(int $fetch_options): Query { @@ -753,7 +834,9 @@ public function setFetchOptions(int $fetch_options): Query { } /** + * Set the fetch option flag * @param int $fetch_options + * * @return Query */ public function fetchOptions(int $fetch_options): Query { @@ -761,21 +844,27 @@ public function fetchOptions(int $fetch_options): Query { } /** - * @return int + * Get the fetch option flag + * + * @return ?int */ - public function getFetchOptions() { + public function getFetchOptions(): ?int { return $this->fetch_options; } /** + * Get the fetch body flag + * * @return boolean */ - public function getFetchBody() { + public function getFetchBody(): bool { return $this->fetch_body; } /** + * Set the fetch body flag * @param boolean $fetch_body + * * @return Query */ public function setFetchBody(bool $fetch_body): Query { @@ -784,7 +873,9 @@ public function setFetchBody(bool $fetch_body): Query { } /** + * Set the fetch body flag * @param boolean $fetch_body + * * @return Query */ public function fetchBody(bool $fetch_body): Query { @@ -792,23 +883,29 @@ public function fetchBody(bool $fetch_body): Query { } /** - * @return int + * Get the fetch body flag + * + * @return bool */ - public function getFetchFlags() { + public function getFetchFlags(): bool { return $this->fetch_flags; } /** - * @param int $fetch_flags + * Set the fetch flag + * @param bool $fetch_flags + * * @return Query */ - public function setFetchFlags(int $fetch_flags): Query { + public function setFetchFlags(bool $fetch_flags): Query { $this->fetch_flags = $fetch_flags; return $this; } /** + * Set the fetch order * @param string $fetch_order + * * @return Query */ public function setFetchOrder(string $fetch_order): Query { @@ -822,7 +919,9 @@ public function setFetchOrder(string $fetch_order): Query { } /** + * Set the fetch order * @param string $fetch_order + * * @return Query */ public function fetchOrder(string $fetch_order): Query { @@ -830,6 +929,8 @@ public function fetchOrder(string $fetch_order): Query { } /** + * Get the fetch order + * * @return string */ public function getFetchOrder(): string { @@ -837,6 +938,8 @@ public function getFetchOrder(): string { } /** + * Set the fetch order to ascending + * * @return Query */ public function setFetchOrderAsc(): Query { @@ -844,6 +947,8 @@ public function setFetchOrderAsc(): Query { } /** + * Set the fetch order to ascending + * * @return Query */ public function fetchOrderAsc(): Query { @@ -851,6 +956,8 @@ public function fetchOrderAsc(): Query { } /** + * Set the fetch order to descending + * * @return Query */ public function setFetchOrderDesc(): Query { @@ -858,6 +965,8 @@ public function setFetchOrderDesc(): Query { } /** + * Set the fetch order to descending + * * @return Query */ public function fetchOrderDesc(): Query { @@ -865,18 +974,20 @@ public function fetchOrderDesc(): Query { } /** - * @return Query + * Set soft fail mode * @var boolean $state * + * @return Query */ public function softFail(bool $state = true): Query { return $this->setSoftFail($state); } /** - * @return Query - * @var boolean $state + * Set soft fail mode * + * @var boolean $state + * @return Query */ public function setSoftFail(bool $state = true): Query { $this->soft_fail = $state; @@ -885,6 +996,8 @@ public function setSoftFail(bool $state = true): Query { } /** + * Get soft fail mode + * * @return boolean */ public function getSoftFail(): bool { @@ -897,7 +1010,7 @@ public function getSoftFail(): bool { * * @throws GetMessagesFailedException */ - protected function handleException(int $uid) { + protected function handleException(int $uid): void { if ($this->soft_fail === false && $this->hasError($uid)) { $error = $this->getError($uid); throw new GetMessagesFailedException($error->getMessage(), 0, $error); @@ -909,17 +1022,17 @@ protected function handleException(int $uid) { * @param integer $uid * @param Exception $error */ - protected function setError(int $uid, Exception $error) { + protected function setError(int $uid, Exception $error): void { $this->errors[$uid] = $error; } /** * Check if there are any errors / exceptions present - * @return boolean - * @var integer|null $uid + * @var ?integer $uid * + * @return boolean */ - public function hasErrors($uid = null): bool { + public function hasErrors(?int $uid = null): bool { if ($uid !== null) { return $this->hasError($uid); } @@ -928,9 +1041,9 @@ public function hasErrors($uid = null): bool { /** * Check if there is an error / exception present - * @return boolean * @var integer $uid * + * @return boolean */ public function hasError(int $uid): bool { return isset($this->errors[$uid]); @@ -956,21 +1069,21 @@ public function getErrors(): array { /** * Get a specific error / exception - * @return Exception|null * @var integer $uid * + * @return Exception|null */ - public function error(int $uid) { + public function error(int $uid): ?Exception { return $this->getError($uid); } /** * Get a specific error / exception - * @return Exception|null * @var integer $uid * + * @return ?Exception */ - public function getError(int $uid) { + public function getError(int $uid): ?Exception { if ($this->hasError($uid)) { return $this->errors[$uid]; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/WhereQuery.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/WhereQuery.php index b6483f6de..b218e5456 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/WhereQuery.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Query/WhereQuery.php @@ -58,7 +58,7 @@ class WhereQuery extends Query { /** * @var array $available_criteria */ - protected $available_criteria = [ + protected array $available_criteria = [ 'OR', 'AND', 'ALL', 'ANSWERED', 'BCC', 'BEFORE', 'BODY', 'CC', 'DELETED', 'FLAGGED', 'FROM', 'KEYWORD', 'NEW', 'NOT', 'OLD', 'ON', 'RECENT', 'SEEN', 'SINCE', 'SUBJECT', 'TEXT', 'TO', @@ -74,7 +74,7 @@ class WhereQuery extends Query { * @throws InvalidWhereQueryCriteriaException * @throws MethodNotFoundException */ - public function __call(string $name, $arguments) { + public function __call(string $name, ?array $arguments) { $that = $this; $name = Str::camel($name); @@ -84,7 +84,7 @@ public function __call(string $name, $arguments) { $name = substr($name, 3); } - if (strpos(strtolower($name), "where") === false) { + if (!str_contains(strtolower($name), "where")) { $method = 'where' . ucfirst($name); } else { $method = lcfirst($name); @@ -106,7 +106,7 @@ public function __call(string $name, $arguments) { */ protected function validate_criteria($criteria): string { $command = strtoupper($criteria); - if (substr($command, 0, 7) === "CUSTOM ") { + if (str_starts_with($command, "CUSTOM ")) { return substr($criteria, 7); } if (in_array($command, $this->available_criteria) === false) { @@ -119,7 +119,7 @@ protected function validate_criteria($criteria): string { /** * Register search parameters * @param mixed $criteria - * @param null $value + * @param mixed $value * * @return $this * @throws InvalidWhereQueryCriteriaException @@ -132,7 +132,7 @@ protected function validate_criteria($criteria): string { * $query->where(["FROM" => "someone@email.tld", "SEEN"]); * $query->where("FROM", "someone@email.tld")->where("SEEN"); */ - public function where($criteria, $value = null): WhereQuery { + public function where(mixed $criteria, mixed $value = null): WhereQuery { if (is_array($criteria)) { foreach ($criteria as $key => $value) { if (is_numeric($key)) { @@ -155,11 +155,11 @@ public function where($criteria, $value = null): WhereQuery { * * @throws InvalidWhereQueryCriteriaException */ - protected function push_search_criteria(string $criteria, $value){ + protected function push_search_criteria(string $criteria, mixed $value){ $criteria = $this->validate_criteria($criteria); $value = $this->parse_value($value); - if ($value === null || $value === '') { + if ($value === '') { $this->query->push([$criteria]); } else { $this->query->push([$criteria, $value]); @@ -167,7 +167,7 @@ protected function push_search_criteria(string $criteria, $value){ } /** - * @param Closure $closure + * @param Closure|null $closure * * @return $this */ @@ -179,7 +179,7 @@ public function orWhere(Closure $closure = null): WhereQuery { } /** - * @param Closure $closure + * @param Closure|null $closure * * @return $this */ @@ -222,7 +222,7 @@ public function whereBcc(string $value): WhereQuery { * @throws InvalidWhereQueryCriteriaException * @throws MessageSearchValidationException */ - public function whereBefore($value): WhereQuery { + public function whereBefore(mixed $value): WhereQuery { $date = $this->parse_date($value); return $this->where('BEFORE', $date); } @@ -316,7 +316,7 @@ public function whereOld(): WhereQuery { * @throws MessageSearchValidationException * @throws InvalidWhereQueryCriteriaException */ - public function whereOn($value): WhereQuery { + public function whereOn(mixed $value): WhereQuery { $date = $this->parse_date($value); return $this->where('ON', $date); } @@ -344,7 +344,7 @@ public function whereSeen(): WhereQuery { * @throws MessageSearchValidationException * @throws InvalidWhereQueryCriteriaException */ - public function whereSince($value): WhereQuery { + public function whereSince(mixed $value): WhereQuery { $date = $this->parse_date($value); return $this->where('SINCE', $date); } @@ -489,7 +489,7 @@ public function whereLanguage($country_code): WhereQuery { * @return WhereQuery * @throws InvalidWhereQueryCriteriaException */ - public function whereUid($uid): WhereQuery { + public function whereUid(int|string $uid): WhereQuery { return $this->where('UID', $uid); } @@ -513,9 +513,9 @@ public function whereUidIn(array $uids): WhereQuery { * @param mixed $value * @param callable $callback * @param callable|null $default - * @return $this|mixed + * @return $this|null */ - public function when($value, callable $callback, $default = null) { + public function when(mixed $value, callable $callback, ?callable $default = null): mixed { if ($value) { return $callback($this, $value) ?: $this; } elseif ($default) { @@ -534,7 +534,7 @@ public function when($value, callable $callback, $default = null) { * @param callable|null $default * @return $this|mixed */ - public function unless($value, callable $callback, $default = null) { + public function unless(mixed $value, callable $callback, ?callable $default = null): mixed { if (!$value) { return $callback($this, $value) ?: $this; } elseif ($default) { @@ -543,4 +543,13 @@ public function unless($value, callable $callback, $default = null) { return $this; } + + /** + * Get all available search criteria + * + * @return array|string[] + */ + public function getAvailableCriteria(): array { + return $this->available_criteria; + } } \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Structure.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Structure.php index 40ddc3a5e..745a6234f 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Structure.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Structure.php @@ -28,33 +28,33 @@ class Structure { * * @var string $raw */ - public $raw = ""; + public string $raw = ""; /** * @var Header $header */ - private $header = null; + private Header $header; /** * Message type (if multipart or not) * * @var int $type */ - public $type = IMAP::MESSAGE_TYPE_TEXT; + public int $type = IMAP::MESSAGE_TYPE_TEXT; /** * All available parts * * @var Part[] $parts */ - public $parts = []; + public array $parts = []; /** * Config holder * * @var array $config */ - protected $config = []; + protected array $config = []; /** * Structure constructor. @@ -77,7 +77,7 @@ public function __construct($raw_structure, Header $header) { * @throws MessageContentFetchingException * @throws InvalidMessageDateException */ - protected function parse(){ + protected function parse(): void { $this->findContentType(); $this->parts = $this->find_parts(); } @@ -85,9 +85,8 @@ protected function parse(){ /** * Determine the message content type */ - public function findContentType(){ - $content_type = $this->header->get("content_type"); - $content_type = (is_array($content_type)) ? implode(' ', $content_type) : $content_type; + public function findContentType(): void { + $content_type = $this->header->get("content_type")->first(); if($content_type && stripos($content_type, 'multipart') === 0) { $this->type = IMAP::MESSAGE_TYPE_MULTIPART; }else{ @@ -96,7 +95,7 @@ public function findContentType(){ } /** - * Find all available headers and return the left over body segment + * Find all available headers and return the leftover body segment * @var string $context * @var integer $part_number * @@ -115,6 +114,7 @@ private function parsePart(string $context, int $part_number = 0): array { if (($boundary = $headers->getBoundary()) !== null) { return $this->detectParts($boundary, $body, $part_number); } + return [new Part($body, $headers, $part_number)]; } @@ -131,7 +131,7 @@ private function detectParts(string $boundary, string $context, int $part_number $final_parts = []; foreach($base_parts as $ctx) { $ctx = substr($ctx, 2); - if ($ctx !== "--" && $ctx != "") { + if ($ctx !== "--" && $ctx != "" && $ctx != "\r\n") { $parts = $this->parsePart($ctx, $part_number); foreach ($parts as $part) { $final_parts[] = $part; @@ -161,14 +161,4 @@ public function find_parts(): array { return [new Part($this->raw, $this->header)]; } - - /** - * Try to find a boundary if possible - * - * @return string|null - * @Depricated since version 2.4.4 - */ - public function getBoundary(){ - return $this->header->getBoundary(); - } } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/AttachmentCollection.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/AttachmentCollection.php index 8b3f9c322..9d2af20d4 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/AttachmentCollection.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/AttachmentCollection.php @@ -12,10 +12,14 @@ namespace Webklex\PHPIMAP\Support; +use Illuminate\Support\Collection; +use Webklex\PHPIMAP\Attachment; + /** * Class AttachmentCollection * * @package Webklex\PHPIMAP\Support + * @implements Collection */ class AttachmentCollection extends PaginatedCollection { diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FlagCollection.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FlagCollection.php index 929594ee7..b8bf352c6 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FlagCollection.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FlagCollection.php @@ -12,10 +12,13 @@ namespace Webklex\PHPIMAP\Support; +use Illuminate\Support\Collection; + /** * Class FlagCollection * * @package Webklex\PHPIMAP\Support + * @implements Collection */ class FlagCollection extends PaginatedCollection { diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FolderCollection.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FolderCollection.php index f74ec4d49..212ddb0aa 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FolderCollection.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/FolderCollection.php @@ -12,10 +12,14 @@ namespace Webklex\PHPIMAP\Support; +use Illuminate\Support\Collection; +use Webklex\PHPIMAP\Folder; + /** * Class FolderCollection * * @package Webklex\PHPIMAP\Support + * @implements Collection */ class FolderCollection extends PaginatedCollection { diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/AttachmentMask.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/AttachmentMask.php index 1f9855e8b..d79b948aa 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/AttachmentMask.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/AttachmentMask.php @@ -22,14 +22,14 @@ class AttachmentMask extends Mask { /** @var Attachment $parent */ - protected $parent; + protected mixed $parent; /** * Get the attachment content base64 encoded * * @return string|null */ - public function getContentBase64Encoded() { + public function getContentBase64Encoded(): ?string { return base64_encode($this->parent->content); } @@ -38,7 +38,7 @@ public function getContentBase64Encoded() { * * @return string|null */ - public function getImageSrc() { + public function getImageSrc(): ?string { return 'data:'.$this->parent->content_type.';base64,'.$this->getContentBase64Encoded(); } } \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/Mask.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/Mask.php index 1ab17d5a8..2101f5742 100755 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/Mask.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/Mask.php @@ -27,14 +27,14 @@ class Mask { * * @var array $attributes */ - protected $attributes = []; + protected array $attributes = []; /** * Parent instance * - * @var object $parent + * @var mixed $parent */ - protected $parent; + protected mixed $parent; /** * Mask constructor. @@ -53,7 +53,7 @@ public function __construct($parent) { /** * Boot method made to be used by any custom mask */ - protected function boot(){} + protected function boot(): void {} /** * Call dynamic attribute setter and getter methods and inherit the parent calls @@ -119,9 +119,9 @@ public function __get($name) { /** * Get the parent instance * - * @return object + * @return mixed */ - public function getParent(){ + public function getParent(): mixed { return $this->parent; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/MessageMask.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/MessageMask.php index d072e8b64..4cc3d5c05 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/MessageMask.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/Masks/MessageMask.php @@ -23,7 +23,7 @@ class MessageMask extends Mask { /** @var Message $parent */ - protected $parent; + protected mixed $parent; /** * Get the message html body @@ -44,15 +44,15 @@ public function getHtmlBody(){ /** * Get the Message html body filtered by an optional callback - * @param callable|bool $callback + * @param callable|null $callback * * @return string|null */ - public function getCustomHTMLBody($callback = false) { + public function getCustomHTMLBody(?callable $callback = null): ?string { $body = $this->getHtmlBody(); if($body === null) return null; - if ($callback !== false) { + if ($callback !== null) { $aAttachment = $this->parent->getAttachments(); $aAttachment->each(function($oAttachment) use(&$body, $callback) { /** @var Attachment $oAttachment */ @@ -73,7 +73,7 @@ public function getCustomHTMLBody($callback = false) { * * @return string|null */ - public function getHTMLBodyWithEmbeddedBase64Images() { + public function getHTMLBodyWithEmbeddedBase64Images(): ?string { return $this->getCustomHTMLBody(function($body, $oAttachment){ /** @var Attachment $oAttachment */ if ($oAttachment->id) { diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/MessageCollection.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/MessageCollection.php index 6d1249fae..1ca97a70c 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/MessageCollection.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/MessageCollection.php @@ -12,11 +12,15 @@ namespace Webklex\PHPIMAP\Support; +use Illuminate\Support\Collection; +use Webklex\PHPIMAP\Message; + /** * Class MessageCollection * * @package Webklex\PHPIMAP\Support + * @implements Collection */ class MessageCollection extends PaginatedCollection { -} \ No newline at end of file +} diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/PaginatedCollection.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/PaginatedCollection.php index 292afd0ad..3b3470e96 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/PaginatedCollection.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Support/PaginatedCollection.php @@ -28,7 +28,7 @@ class PaginatedCollection extends Collection { * * @var int $total */ - protected $total; + protected int $total = 0; /** * Paginate the current collection. @@ -39,7 +39,7 @@ class PaginatedCollection extends Collection { * * @return LengthAwarePaginator */ - public function paginate(int $per_page = 15, $page = null, string $page_name = 'page', bool $prepaginated = false): LengthAwarePaginator { + public function paginate(int $per_page = 15, ?int $page = null, string $page_name = 'page', bool $prepaginated = false): LengthAwarePaginator { $page = $page ?: Paginator::resolveCurrentPage($page_name); $total = $this->total ?: $this->count(); @@ -57,12 +57,12 @@ public function paginate(int $per_page = 15, $page = null, string $page_name = ' * @param array $items * @param int $total * @param int $per_page - * @param int|null $current_page + * @param int|null $current_page * @param array $options * * @return LengthAwarePaginator */ - protected function paginator(array $items, int $total, int $per_page, $current_page, array $options): LengthAwarePaginator { + protected function paginator(array $items, int $total, int $per_page, ?int $current_page, array $options): LengthAwarePaginator { return new LengthAwarePaginator($items, $total, $per_page, $current_page, $options); } @@ -72,7 +72,7 @@ protected function paginator(array $items, int $total, int $per_page, $current_p * * @return int|null */ - public function total($total = null) { + public function total($total = null): ?int { if($total === null) { return $this->total; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/src/Traits/HasEvents.php b/lam/lib/3rdParty/composer/webklex/php-imap/src/Traits/HasEvents.php index 56a60915c..3b6902edc 100644 --- a/lam/lib/3rdParty/composer/webklex/php-imap/src/Traits/HasEvents.php +++ b/lam/lib/3rdParty/composer/webklex/php-imap/src/Traits/HasEvents.php @@ -28,15 +28,15 @@ trait HasEvents { * * @var array $events */ - protected $events = []; + protected array $events = []; /** * Set a specific event - * @param $section - * @param $event - * @param $class + * @param string $section + * @param string $event + * @param mixed $class */ - public function setEvent($section, $event, $class) { + public function setEvent(string $section, string $event, mixed $class): void { if (isset($this->events[$section])) { $this->events[$section][$event] = $class; } @@ -44,21 +44,21 @@ public function setEvent($section, $event, $class) { /** * Set all events - * @param $events + * @param array $events */ - public function setEvents($events) { + public function setEvents(array $events): void { $this->events = $events; } /** * Get a specific event callback - * @param $section - * @param $event + * @param string $section + * @param string $event * * @return Event|string * @throws EventNotFoundException */ - public function getEvent($section, $event) { + public function getEvent(string $section, string $event): Event|string { if (isset($this->events[$section])) { return $this->events[$section][$event]; } diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/AddressTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/AddressTest.php new file mode 100644 index 000000000..442462fb1 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/AddressTest.php @@ -0,0 +1,72 @@ + "Username", + "mailbox" => "info", + "host" => "domain.tld", + "mail" => "info@domain.tld", + "full" => "Username ", + ]; + + /** + * Address test + * + * @return void + */ + public function testAddress(): void { + $address = new Address((object)$this->data); + + self::assertSame("Username", $address->personal); + self::assertSame("info", $address->mailbox); + self::assertSame("domain.tld", $address->host); + self::assertSame("info@domain.tld", $address->mail); + self::assertSame("Username ", $address->full); + } + + /** + * Test Address to string conversion + * + * @return void + */ + public function testAddressToStringConversion(): void { + $address = new Address((object)$this->data); + + self::assertSame("Username ", (string)$address); + } + + /** + * Test Address serialization + * + * @return void + */ + public function testAddressSerialization(): void { + $address = new Address((object)$this->data); + + foreach($address as $key => $value) { + self::assertSame($this->data[$key], $value); + } + + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/AttributeTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/AttributeTest.php new file mode 100644 index 000000000..8374894f7 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/AttributeTest.php @@ -0,0 +1,75 @@ +toString()); + self::assertSame("foo", $attribute->getName()); + self::assertSame("foos", $attribute->setName("foos")->getName()); + } + + /** + * Date Attribute test + * + * @return void + */ + public function testDateAttribute(): void { + $attribute = new Attribute("foo", "2022-12-26 08:07:14 GMT-0800"); + + self::assertInstanceOf(Carbon::class, $attribute->toDate()); + self::assertSame("2022-12-26 08:07:14 GMT-0800", $attribute->toDate()->format("Y-m-d H:i:s T")); + } + + /** + * Array Attribute test + * + * @return void + */ + public function testArrayAttribute(): void { + $attribute = new Attribute("foo", ["bar"]); + + self::assertSame("bar", $attribute->toString()); + + $attribute->add("bars"); + self::assertSame(true, $attribute->has(1)); + self::assertSame("bars", $attribute->get(1)); + self::assertSame(true, $attribute->contains("bars")); + self::assertSame("foo, bars", $attribute->set("foo", 0)->toString()); + + $attribute->remove(0); + self::assertSame("bars", $attribute->toString()); + + self::assertSame("bars, foos", $attribute->merge(["foos", "bars"], true)->toString()); + self::assertSame("bars, foos, foos, donk", $attribute->merge(["foos", "donk"], false)->toString()); + + self::assertSame(4, $attribute->count()); + + self::assertSame("donk", $attribute->last()); + self::assertSame("bars", $attribute->first()); + + self::assertSame(["bars", "foos", "foos", "donk"], array_values($attribute->all())); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientManagerTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientManagerTest.php new file mode 100644 index 000000000..80ec4ceb8 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientManagerTest.php @@ -0,0 +1,91 @@ +cm = new ClientManager(); + } + + /** + * Test if the config can be accessed + * + * @return void + */ + public function testConfigAccessorAccount(): void { + self::assertSame("default", ClientManager::get("default")); + self::assertSame("d-M-Y", ClientManager::get("date_format")); + self::assertSame(IMAP::FT_PEEK, ClientManager::get("options.fetch")); + self::assertSame([], ClientManager::get("options.open")); + } + + /** + * Test creating a client instance + * + * @throws MaskNotFoundException + */ + public function testMakeClient(): void { + self::assertInstanceOf(Client::class, $this->cm->make([])); + } + + /** + * Test accessing accounts + * + * @throws MaskNotFoundException + */ + public function testAccountAccessor(): void { + self::assertSame("default", $this->cm->getDefaultAccount()); + self::assertNotEmpty($this->cm->account("default")); + + $this->cm->setDefaultAccount("foo"); + self::assertSame("foo", $this->cm->getDefaultAccount()); + $this->cm->setDefaultAccount("default"); + } + + /** + * Test setting a config + * + * @throws MaskNotFoundException + */ + public function testSetConfig(): void { + $config = [ + "default" => "foo", + "options" => [ + "fetch" => IMAP::ST_MSGN, + "open" => "foo" + ] + ]; + $cm = new ClientManager($config); + + self::assertSame("foo", $cm->getDefaultAccount()); + self::assertInstanceOf(Client::class, $cm->account("foo")); + self::assertSame(IMAP::ST_MSGN, $cm->get("options.fetch")); + self::assertSame(false, is_array($cm->get("options.open"))); + + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientTest.php new file mode 100644 index 000000000..8d9f8e66d --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ClientTest.php @@ -0,0 +1,308 @@ +client = new Client([ + 'protocol' => 'imap', + 'encryption' => 'ssl', + 'username' => 'foo@domain.tld', + 'password' => 'bar', + 'proxy' => [ + 'socket' => null, + 'request_fulluri' => false, + 'username' => null, + 'password' => null, + ], + ]); + } + + /** + * Client test + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws RuntimeException + */ + public function testClient(): void { + $this->createNewProtocolMockup(); + + self::assertInstanceOf(ImapProtocol::class, $this->client->getConnection()); + self::assertSame(true, $this->client->isConnected()); + self::assertSame(false, $this->client->checkConnection()); + self::assertSame(30, $this->client->getTimeout()); + self::assertSame(MessageMask::class, $this->client->getDefaultMessageMask()); + self::assertSame(AttachmentMask::class, $this->client->getDefaultAttachmentMask()); + self::assertArrayHasKey("new", $this->client->getDefaultEvents("message")); + } + + public function testClientLogout(): void { + $this->createNewProtocolMockup(); + + $this->protocol->expects($this->any())->method('logout')->willReturn(Response::empty()->setResponse([ + 0 => "BYE Logging out\r\n", + 1 => "OK Logout completed (0.001 + 0.000 secs).\r\n", + ])); + self::assertInstanceOf(Client::class, $this->client->disconnect()); + + } + + public function testClientExpunge(): void { + $this->createNewProtocolMockup(); + $this->protocol->expects($this->any())->method('expunge')->willReturn(Response::empty()->setResponse([ + 0 => "OK", + 1 => "Expunge", + 2 => "completed", + 3 => [ + 0 => "0.001", + 1 => "+", + 2 => "0.000", + 3 => "secs).", + ], + ])); + self::assertNotEmpty($this->client->expunge()); + + } + + public function testClientFolders(): void { + $this->createNewProtocolMockup(); + $this->protocol->expects($this->any())->method('expunge')->willReturn(Response::empty()->setResponse([ + 0 => "OK", + 1 => "Expunge", + 2 => "completed", + 3 => [ + 0 => "0.001", + 1 => "+", + 2 => "0.000", + 3 => "secs).", + ], + ])); + + $this->protocol->expects($this->any())->method('selectFolder')->willReturn(Response::empty()->setResponse([ + "flags" => [ + 0 => [ + 0 => "\Answered", + 1 => "\Flagged", + 2 => "\Deleted", + 3 => "\Seen", + 4 => "\Draft", + 5 => "NonJunk", + 6 => "unknown-1", + ], + ], + "exists" => 139, + "recent" => 0, + "unseen" => 94, + "uidvalidity" => 1488899637, + "uidnext" => 278, + ])); + self::assertNotEmpty($this->client->openFolder("INBOX")); + self::assertSame("INBOX", $this->client->getFolderPath()); + + $this->protocol->expects($this->any())->method('examineFolder')->willReturn(Response::empty()->setResponse([ + "flags" => [ + 0 => [ + 0 => "\Answered", + 1 => "\Flagged", + 2 => "\Deleted", + 3 => "\Seen", + 4 => "\Draft", + 5 => "NonJunk", + 6 => "unknown-1", + ], + ], + "exists" => 139, + "recent" => 0, + "unseen" => 94, + "uidvalidity" => 1488899637, + "uidnext" => 278, + ])); + self::assertNotEmpty($this->client->checkFolder("INBOX")); + + $this->protocol->expects($this->any())->method('folders')->with($this->identicalTo(""), $this->identicalTo("*"))->willReturn(Response::empty()->setResponse([ + "INBOX" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasChildren", + ], + ], + "INBOX.new" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.9AL56dEMTTgUKOAz" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.U9PsHCvXxAffYvie" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.Trash" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + 1 => "\Trash", + ], + ], + "INBOX.processing" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.Sent" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + 1 => "\Sent", + ], + ], + "INBOX.OzDWCXKV3t241koc" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.5F3bIVTtBcJEqIVe" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.8J3rll6eOBWnTxIU" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + "INBOX.Junk" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + 1 => "\Junk", + ], + ], + "INBOX.Drafts" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + 1 => "\Drafts", + ], + ], + "INBOX.test" => [ + "delimiter" => ".", + "flags" => [ + 0 => "\HasNoChildren", + ], + ], + ])); + + $this->protocol->expects($this->any())->method('createFolder')->willReturn(Response::empty()->setResponse([ + 0 => "OK Create completed (0.004 + 0.000 + 0.003 secs).\r\n", + ])); + self::assertNotEmpty($this->client->createFolder("INBOX.new")); + + $this->protocol->expects($this->any())->method('deleteFolder')->willReturn(Response::empty()->setResponse([ + 0 => "OK Delete completed (0.007 + 0.000 + 0.006 secs).\r\n", + ])); + self::assertNotEmpty($this->client->deleteFolder("INBOX.new")); + + self::assertInstanceOf(Folder::class, $this->client->getFolderByPath("INBOX.new")); + self::assertInstanceOf(Folder::class, $this->client->getFolderByName("new")); + self::assertInstanceOf(Folder::class, $this->client->getFolder("INBOX.new", ".")); + self::assertInstanceOf(Folder::class, $this->client->getFolder("new")); + } + + public function testClientId(): void { + $this->createNewProtocolMockup(); + $this->protocol->expects($this->any())->method('ID')->willReturn(Response::empty()->setResponse([ + 0 => "ID (\"name\" \"Dovecot\")\r\n", + 1 => "OK ID completed (0.001 + 0.000 secs).\r\n" + + ])); + self::assertSame("ID (\"name\" \"Dovecot\")\r\n", $this->client->Id()[0]); + + } + + public function testClientConfig(): void { + $config = $this->client->getConfig(); + self::assertSame("foo@domain.tld", $config["username"]); + self::assertSame("bar", $config["password"]); + self::assertSame("localhost", $config["host"]); + self::assertSame(true, $config["validate_cert"]); + self::assertSame(993, $config["port"]); + + $this->client->setConfig([ + "host" => "domain.tld", + 'password' => 'bar', + ]); + $config = $this->client->getConfig(); + self::assertSame("bar", $config["password"]); + self::assertSame("domain.tld", $config["host"]); + self::assertSame(true, $config["validate_cert"]); + } + + protected function createNewProtocolMockup() { + $this->protocol = $this->createMock(ImapProtocol::class); + + $this->protocol->expects($this->any())->method('connected')->willReturn(true); + $this->protocol->expects($this->any())->method('getConnectionTimeout')->willReturn(30); + + $this->protocol + ->expects($this->any()) + ->method('createStream') + //->will($this->onConsecutiveCalls(true)); + ->willReturn(true); + + $this->client->connection = $this->protocol; + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/HeaderTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/HeaderTest.php new file mode 100644 index 000000000..7afec065b --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/HeaderTest.php @@ -0,0 +1,142 @@ +get("subject"); + $returnPath = $header->get("Return-Path"); + /** @var Carbon $date */ + $date = $header->get("date")->first(); + /** @var Address $from */ + $from = $header->get("from")->first(); + /** @var Address $to */ + $to = $header->get("to")->first(); + + self::assertSame($raw_header, $header->raw); + self::assertInstanceOf(Attribute::class, $subject); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", $subject->toString()); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", (string)$header->subject); + self::assertSame("", $returnPath->toString()); + self::assertSame("return_path", $returnPath->getName()); + self::assertSame("-4.299", (string)$header->get("X-Spam-Score")); + self::assertSame("Webklex/php-imap/issues/349/1365266070@github.com", (string)$header->get("Message-ID")); + self::assertSame(6, $header->get("received")->count()); + self::assertSame(IMAP::MESSAGE_PRIORITY_UNKNOWN, (int)$header->get("priority")()); + + self::assertSame("Username", $from->personal); + self::assertSame("notifications", $from->mailbox); + self::assertSame("github.com", $from->host); + self::assertSame("notifications@github.com", $from->mail); + self::assertSame("Username ", $from->full); + + self::assertSame("Webklex/php-imap", $to->personal); + self::assertSame("php-imap", $to->mailbox); + self::assertSame("noreply.github.com", $to->host); + self::assertSame("php-imap@noreply.github.com", $to->mail); + self::assertSame("Webklex/php-imap ", $to->full); + + self::assertInstanceOf(Carbon::class, $date); + self::assertSame("2022-12-26 08:07:14 GMT-0800", $date->format("Y-m-d H:i:s T")); + + self::assertSame(48, count($header->getAttributes())); + } + + public function testRfc822ParseHeaders() { + $mock = $this->getMockBuilder(Header::class) + ->disableOriginalConstructor() + ->onlyMethods([]) + ->getMock(); + + $config = new \ReflectionProperty($mock, 'config'); + $config->setAccessible(true); + $config->setValue($mock, ['rfc822' => true]); + + $mockHeader = "Content-Type: text/csv; charset=WINDOWS-1252; name*0=\"TH_Is_a_F ile name example 20221013.c\"; name*1=sv\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Disposition: attachment; filename*0=\"TH_Is_a_F ile name example 20221013.c\"; filename*1=\"sv\"\r\n"; + + $expected = new \stdClass(); + $expected->content_type = 'text/csv; charset=WINDOWS-1252; name*0="TH_Is_a_F ile name example 20221013.c"; name*1=sv'; + $expected->content_transfer_encoding = 'quoted-printable'; + $expected->content_disposition = 'attachment; filename*0="TH_Is_a_F ile name example 20221013.c"; filename*1="sv"'; + + $this->assertEquals($expected, $mock->rfc822_parse_headers($mockHeader)); + } + + public function testExtractHeaderExtensions() { + $mock = $this->getMockBuilder(Header::class) + ->disableOriginalConstructor() + ->onlyMethods([]) + ->getMock(); + + $method = new \ReflectionMethod($mock, 'extractHeaderExtensions'); + $method->setAccessible(true); + + $mockAttributes = [ + 'content_type' => new Attribute('content_type', 'text/csv; charset=WINDOWS-1252; name*0="TH_Is_a_F ile name example 20221013.c"; name*1=sv'), + 'content_transfer_encoding' => new Attribute('content_transfer_encoding', 'quoted-printable'), + 'content_disposition' => new Attribute('content_disposition', 'attachment; filename*0="TH_Is_a_F ile name example 20221013.c"; filename*1="sv"; attribute_test=attribute_test_value'), + ]; + + $attributes = new \ReflectionProperty($mock, 'attributes'); + $attributes->setAccessible(true); + $attributes->setValue($mock, $mockAttributes); + + $method->invoke($mock); + + $this->assertArrayHasKey('filename', $mock->getAttributes()); + $this->assertArrayNotHasKey('filename*0', $mock->getAttributes()); + $this->assertEquals('TH_Is_a_F ile name example 20221013.csv', $mock->get('filename')); + + $this->assertArrayHasKey('name', $mock->getAttributes()); + $this->assertArrayNotHasKey('name*0', $mock->getAttributes()); + $this->assertEquals('TH_Is_a_F ile name example 20221013.csv', $mock->get('name')); + + $this->assertArrayHasKey('content_type', $mock->getAttributes()); + $this->assertEquals('text/csv', $mock->get('content_type')->last()); + + $this->assertArrayHasKey('charset', $mock->getAttributes()); + $this->assertEquals('WINDOWS-1252', $mock->get('charset')->last()); + + $this->assertArrayHasKey('content_transfer_encoding', $mock->getAttributes()); + $this->assertEquals('quoted-printable', $mock->get('content_transfer_encoding')); + + $this->assertArrayHasKey('content_disposition', $mock->getAttributes()); + $this->assertEquals('attachment', $mock->get('content_disposition')->last()); + $this->assertEquals('quoted-printable', $mock->get('content_transfer_encoding')); + + $this->assertArrayHasKey('attribute_test', $mock->getAttributes()); + $this->assertEquals('attribute_test_value', $mock->get('attribute_test')); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/ImapProtocolTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ImapProtocolTest.php new file mode 100644 index 000000000..4d7443327 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/ImapProtocolTest.php @@ -0,0 +1,39 @@ +getCertValidation()); + self::assertSame("", $protocol->getEncryption()); + + $protocol->setCertValidation(true); + $protocol->setEncryption("ssl"); + + self::assertSame(true, $protocol->getCertValidation()); + self::assertSame("ssl", $protocol->getEncryption()); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/InitialTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/InitialTest.php deleted file mode 100644 index fb854db4a..000000000 --- a/lam/lib/3rdParty/composer/webklex/php-imap/tests/InitialTest.php +++ /dev/null @@ -1,26 +0,0 @@ -cm = new ClientManager(); - } - - public function testConfigDefaultAccount() { - $this->assertEquals("default", ClientManager::get("default")); - } -} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/MessageTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/MessageTest.php new file mode 100644 index 000000000..3f8549182 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/MessageTest.php @@ -0,0 +1,298 @@ +client = new Client([ + 'protocol' => 'imap', + 'encryption' => 'ssl', + 'username' => 'foo@domain.tld', + 'password' => 'bar', + 'proxy' => [ + 'socket' => null, + 'request_fulluri' => false, + 'username' => null, + 'password' => null, + ], + ]); + } + + /** + * Message test + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageNotFoundException + * @throws MessageSizeFetchingException + * @throws ReflectionException + * @throws ResponseException + * @throws RuntimeException + */ + public function testMessage(): void { + $this->createNewProtocolMockup(); + + $email = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, "messages", "1366671050@github.com.eml"])); + if(!str_contains($email, "\r\n")){ + $email = str_replace("\n", "\r\n", $email); + } + + $raw_header = substr($email, 0, strpos($email, "\r\n\r\n")); + $raw_body = substr($email, strlen($raw_header)+8); + + $this->protocol->expects($this->any())->method('getUid')->willReturn(Response::empty()->setResult(22)); + $this->protocol->expects($this->any())->method('getMessageNumber')->willReturn(Response::empty()->setResult(21)); + $this->protocol->expects($this->any())->method('flags')->willReturn(Response::empty()->setResult([22 => [0 => "\\Seen"]])); + + self::assertNotEmpty($this->client->openFolder("INBOX")); + + $message = Message::make(22, null, $this->client, $raw_header, $raw_body, [0 => "\\Seen"], IMAP::ST_UID); + + self::assertInstanceOf(Client::class, $message->getClient()); + self::assertSame(22, $message->uid); + self::assertSame(21, $message->msgn); + self::assertContains("Seen", $message->flags()->toArray()); + + $subject = $message->get("subject"); + $returnPath = $message->get("Return-Path"); + + self::assertInstanceOf(Attribute::class, $subject); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", $subject->toString()); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", (string)$message->subject); + self::assertSame("", $returnPath->toString()); + self::assertSame("return_path", $returnPath->getName()); + self::assertSame("-4.299", (string)$message->get("X-Spam-Score")); + self::assertSame("Webklex/php-imap/issues/349/1365266070@github.com", (string)$message->get("Message-ID")); + self::assertSame(6, $message->get("received")->count()); + self::assertSame(IMAP::MESSAGE_PRIORITY_UNKNOWN, (int)$message->get("priority")()); + } + + /** + * Test getMessageNumber + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetMessageNumber(): void { + $this->createNewProtocolMockup(); + $this->protocol->expects($this->any())->method('getMessageNumber')->willReturn(Response::empty()->setResult("")); + + self::assertNotEmpty($this->client->openFolder("INBOX")); + + try { + $this->client->getConnection()->getMessageNumber(21)->validatedData(); + $this->fail("Message number should not exist"); + } catch (ResponseException $e) { + self::assertTrue(true); + } + + } + + /** + * Test loadMessageFromFile + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageNotFoundException + * @throws ReflectionException + * @throws ResponseException + * @throws RuntimeException + * @throws MessageSizeFetchingException + */ + public function testLoadMessageFromFile(): void { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "messages", "1366671050@github.com.eml"]); + $message = Message::fromFile($filename); + + $subject = $message->get("subject"); + $returnPath = $message->get("Return-Path"); + + self::assertInstanceOf(Attribute::class, $subject); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", $subject->toString()); + self::assertSame("Re: [Webklex/php-imap] Read all folders? (Issue #349)", (string)$message->subject); + self::assertSame("", $returnPath->toString()); + self::assertSame("return_path", $returnPath->getName()); + self::assertSame("-4.299", (string)$message->get("X-Spam-Score")); + self::assertSame("Webklex/php-imap/issues/349/1365266070@github.com", (string)$message->get("Message-ID")); + self::assertSame(6, $message->get("received")->count()); + self::assertSame(IMAP::MESSAGE_PRIORITY_UNKNOWN, (int)$message->get("priority")()); + + self::assertNull($message->getClient()); + self::assertSame(0, $message->uid); + + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "messages", "example_attachment.eml"]); + $message = Message::fromFile($filename); + + $subject = $message->get("subject"); + $returnPath = $message->get("Return-Path"); + + self::assertInstanceOf(Attribute::class, $subject); + self::assertSame("ogqMVHhz7swLaq2PfSWsZj0k99w8wtMbrb4RuHdNg53i76B7icIIM0zIWpwGFtnk", $subject->toString()); + self::assertSame("ogqMVHhz7swLaq2PfSWsZj0k99w8wtMbrb4RuHdNg53i76B7icIIM0zIWpwGFtnk", (string)$message->subject); + self::assertSame("", $returnPath->toString()); + self::assertSame("return_path", $returnPath->getName()); + self::assertSame("1.103", (string)$message->get("X-Spam-Score")); + self::assertSame("d3a5e91963cb805cee975687d5acb1c6@swift.generated", (string)$message->get("Message-ID")); + self::assertSame(5, $message->get("received")->count()); + self::assertSame(IMAP::MESSAGE_PRIORITY_HIGHEST, (int)$message->get("priority")()); + + self::assertNull($message->getClient()); + self::assertSame(0, $message->uid); + self::assertSame(1, $message->getAttachments()->count()); + + /** @var Attachment $attachment */ + $attachment = $message->getAttachments()->first(); + self::assertSame("attachment", $attachment->disposition); + self::assertSame("znk551MP3TP3WPp9Kl1gnLErrWEgkJFAtvaKqkTgrk3dKI8dX38YT8BaVxRcOERN", $attachment->content); + self::assertSame("application/octet-stream", $attachment->content_type); + self::assertSame("6mfFxiU5Yhv9WYJx.txt", $attachment->name); + self::assertSame(2, $attachment->part_number); + self::assertSame("text", $attachment->type); + self::assertNotEmpty($attachment->id); + self::assertSame(90, $attachment->size); + self::assertSame("txt", $attachment->getExtension()); + self::assertInstanceOf(Message::class, $attachment->getMessage()); + self::assertSame("text/plain", $attachment->getMimeType()); + } + + /** + * Test issue #348 + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws ReflectionException + * @throws ResponseException + * @throws RuntimeException + */ + public function testIssue348() { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "messages", "issue-348.eml"]); + $message = Message::fromFile($filename); + + self::assertSame(1, $message->getAttachments()->count()); + + /** @var Attachment $attachment */ + $attachment = $message->getAttachments()->first(); + + self::assertSame("attachment", $attachment->disposition); + self::assertSame("application/pdf", $attachment->content_type); + self::assertSame("Kelvinsong—Font_test_page_bold.pdf", $attachment->name); + self::assertSame(1, $attachment->part_number); + self::assertSame("text", $attachment->type); + self::assertNotEmpty($attachment->id); + self::assertSame(92384, $attachment->size); + self::assertSame("pdf", $attachment->getExtension()); + self::assertInstanceOf(Message::class, $attachment->getMessage()); + self::assertSame("application/pdf", $attachment->getMimeType()); + } + + /** + * Create a new protocol mockup + * + * @return void + */ + protected function createNewProtocolMockup(): void { + $this->protocol = $this->createMock(ImapProtocol::class); + + $this->protocol->expects($this->any())->method('createStream')->willReturn(true); + $this->protocol->expects($this->any())->method('connected')->willReturn(true); + $this->protocol->expects($this->any())->method('getConnectionTimeout')->willReturn(30); + $this->protocol->expects($this->any())->method('logout')->willReturn(Response::empty()->setResponse([ + 0 => "BYE Logging out\r\n", + 1 => "OK Logout completed (0.001 + 0.000 secs).\r\n", + ])); + $this->protocol->expects($this->any())->method('selectFolder')->willReturn(Response::empty()->setResponse([ + "flags" => [ + 0 => [ + 0 => "\Answered", + 1 => "\Flagged", + 2 => "\Deleted", + 3 => "\Seen", + 4 => "\Draft", + 5 => "NonJunk", + 6 => "unknown-1", + ], + ], + "exists" => 139, + "recent" => 0, + "unseen" => 94, + "uidvalidity" => 1488899637, + "uidnext" => 278, + ])); + + $this->client->connection = $this->protocol; + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/PartTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/PartTest.php new file mode 100644 index 000000000..f4653519e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/PartTest.php @@ -0,0 +1,94 @@ +charset); + self::assertSame("text/plain", $part->content_type); + self::assertSame(12, $part->bytes); + self::assertSame(0, $part->part_number); + self::assertSame(false, $part->ifdisposition); + self::assertSame(false, $part->isAttachment()); + self::assertSame("Any updates?", $part->content); + self::assertSame(IMAP::MESSAGE_TYPE_TEXT, $part->type); + self::assertSame(IMAP::MESSAGE_ENC_7BIT, $part->encoding); + } + + /** + * Test parsing a html Part + * @throws InvalidMessageDateException + */ + public function testHTMLPart(): void { + $raw_headers = "Content-Type: text/html;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: 7bit\r\n"; + $raw_body = "\r\n

\r\n

Any updates?

"; + + $headers = new Header($raw_headers); + $part = new Part($raw_body, $headers, 0); + + self::assertSame("UTF-8", $part->charset); + self::assertSame("text/html", $part->content_type); + self::assertSame(39, $part->bytes); + self::assertSame(0, $part->part_number); + self::assertSame(false, $part->ifdisposition); + self::assertSame(false, $part->isAttachment()); + self::assertSame("

\r\n

Any updates?

", $part->content); + self::assertSame(IMAP::MESSAGE_TYPE_TEXT, $part->type); + self::assertSame(IMAP::MESSAGE_ENC_7BIT, $part->encoding); + } + + /** + * Test parsing a html Part + * @throws InvalidMessageDateException + */ + public function testBase64Part(): void { + $raw_headers = "Content-Type: application/octet-stream; name=6mfFxiU5Yhv9WYJx.txt\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=6mfFxiU5Yhv9WYJx.txt\r\n"; + $raw_body = "em5rNTUxTVAzVFAzV1BwOUtsMWduTEVycldFZ2tKRkF0dmFLcWtUZ3JrM2RLSThkWDM4WVQ4QmFW\r\neFJjT0VSTg=="; + + $headers = new Header($raw_headers); + $part = new Part($raw_body, $headers, 0); + + self::assertSame("", $part->charset); + self::assertSame("application/octet-stream", $part->content_type); + self::assertSame(90, $part->bytes); + self::assertSame(0, $part->part_number); + self::assertSame("znk551MP3TP3WPp9Kl1gnLErrWEgkJFAtvaKqkTgrk3dKI8dX38YT8BaVxRcOERN", base64_decode($part->content)); + self::assertSame(true, $part->ifdisposition); + self::assertSame("attachment", $part->disposition); + self::assertSame("6mfFxiU5Yhv9WYJx.txt", $part->name); + self::assertSame("6mfFxiU5Yhv9WYJx.txt", $part->filename); + self::assertSame(true, $part->isAttachment()); + self::assertSame(IMAP::MESSAGE_TYPE_TEXT, $part->type); + self::assertSame(IMAP::MESSAGE_ENC_BASE64, $part->encoding); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/StructureTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/StructureTest.php new file mode 100644 index 000000000..a1df098b0 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/StructureTest.php @@ -0,0 +1,55 @@ +parts)); + + $textPart = $structure->parts[0]; + + self::assertSame("UTF-8", $textPart->charset); + self::assertSame("text/plain", $textPart->content_type); + self::assertSame(278, $textPart->bytes); + + $htmlPart = $structure->parts[1]; + + self::assertSame("UTF-8", $htmlPart->charset); + self::assertSame("text/html", $htmlPart->content_type); + self::assertSame(1478, $htmlPart->bytes); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentEncodedFilenameTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentEncodedFilenameTest.php new file mode 100644 index 000000000..b5da35974 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentEncodedFilenameTest.php @@ -0,0 +1,52 @@ +getFixture("attachment_encoded_filename.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("multipart/mixed", $message->content_type->last()); + self::assertFalse($message->hasTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("Prostřeno_2014_poslední volné termíny.xls", $attachment->filename); + self::assertEquals("Prostřeno_2014_poslední volné termíny.xls", $attachment->name); + self::assertEquals('xls', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/vnd.ms-excel", $attachment->content_type); + self::assertEquals("a0ef7cfbc05b73dbcb298fe0bc224b41900cdaf60f9904e3fea5ba6c7670013c", hash("sha256", $attachment->content)); + self::assertEquals(146, $attachment->size); + self::assertEquals(0, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentLongFilenameTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentLongFilenameTest.php new file mode 100644 index 000000000..650a2dcbd --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentLongFilenameTest.php @@ -0,0 +1,79 @@ +getFixture("attachment_long_filename.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("multipart/mixed", $message->content_type->last()); + self::assertFalse($message->hasTextBody()); + self::assertFalse($message->hasHTMLBody()); + + $attachments = $message->attachments(); + self::assertCount(3, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("Buchungsbestätigung- Rechnung-Geschäftsbedingungen-Nr.B123-45 - XXXX xxxxxxxxxxxxxxxxx XxxX, Lüdxxxxxxxx - VM Klaus XXXXXX - xxxxxxxx.pdf", $attachment->name); + self::assertEquals("Buchungsbestätigung- Rechnung-Geschäftsbedingungen-Nr.B123-45 - XXXXX xxxxxxxxxxxxxxxxx XxxX, Lüxxxxxxxxxx - VM Klaus XXXXXX - xxxxxxxx.pdf", $attachment->filename); + self::assertEquals('text', $attachment->type); + self::assertEquals('pdf', $attachment->getExtension()); + self::assertEquals("text/plain", $attachment->content_type); + self::assertEquals("ca51ce1fb15acc6d69b8a5700256172fcc507e02073e6f19592e341bd6508ab8", hash("sha256", $attachment->content)); + self::assertEquals(4, $attachment->size); + self::assertEquals(0, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('01_A€àäąбيد@Z-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz.txt', $attachment->name); + self::assertEquals("f7b5181985862431bfc443d26e3af2371e20a0afd676eeb9b9595a26d42e0b73", hash("sha256", $attachment->filename)); + self::assertEquals('text', $attachment->type); + self::assertEquals('txt', $attachment->getExtension()); + self::assertEquals("text/plain", $attachment->content_type); + self::assertEquals("ca51ce1fb15acc6d69b8a5700256172fcc507e02073e6f19592e341bd6508ab8", hash("sha256", $attachment->content)); + self::assertEquals(4, $attachment->size); + self::assertEquals(1, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[2]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('02_A€àäąбيد@Z-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz.txt', $attachment->name); + self::assertEquals('02_A€àäąбيد@Z-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstuvz.txt', $attachment->filename); + self::assertEquals('text', $attachment->type); + self::assertEquals("text/plain", $attachment->content_type); + self::assertEquals('txt', $attachment->getExtension()); + self::assertEquals("ca51ce1fb15acc6d69b8a5700256172fcc507e02073e6f19592e341bd6508ab8", hash("sha256", $attachment->content)); + self::assertEquals(4, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentNoDispositionTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentNoDispositionTest.php new file mode 100644 index 000000000..aa1ef9461 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/AttachmentNoDispositionTest.php @@ -0,0 +1,55 @@ +getFixture("attachment_no_disposition.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("multipart/mixed", $message->content_type->last()); + self::assertFalse($message->hasTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('26ed3dd2', $attachment->filename); + self::assertEquals('26ed3dd2', $attachment->id); + self::assertEquals("Prostřeno_2014_poslední volné termíny.xls", $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('xls', $attachment->getExtension()); + self::assertEquals("application/vnd.ms-excel", $attachment->content_type); + self::assertEquals("a0ef7cfbc05b73dbcb298fe0bc224b41900cdaf60f9904e3fea5ba6c7670013c", hash("sha256", $attachment->content)); + self::assertEquals(146, $attachment->size); + self::assertEquals(0, $attachment->part_number); + self::assertNull($attachment->disposition); + self::assertNotEmpty($attachment->id); + self::assertEmpty($attachment->content_id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BccTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BccTest.php new file mode 100644 index 000000000..8de14f62a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BccTest.php @@ -0,0 +1,43 @@ +getFixture("bcc.eml"); + + self::assertEquals("test", $message->subject); + self::assertEquals("", $message->return_path); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("text/plain", $message->content_type); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from); + self::assertEquals("to@here.com", $message->to); + self::assertEquals("A_€@{è_Z ", $message->bcc); + self::assertEquals("sender@here.com", $message->sender); + self::assertEquals("reply-to@here.com", $message->reply_to); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BooleanDecodedContentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BooleanDecodedContentTest.php new file mode 100644 index 000000000..e49229a48 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/BooleanDecodedContentTest.php @@ -0,0 +1,55 @@ +getFixture("boolean_decoded_content.eml"); + + self::assertEquals("Nuu", $message->subject); + self::assertEquals("Here is the problem mail\r\n \r\nBody text", $message->getTextBody()); + self::assertEquals("Here is the problem mail\r\n \r\nBody text", $message->getHTMLBody()); + + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from); + self::assertEquals("to@here.com", $message->to); + + $attachments = $message->getAttachments(); + self::assertCount(1, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("Example Domain.pdf", $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('pdf', $attachment->getExtension()); + self::assertEquals("application/pdf", $attachment->content_type); + self::assertEquals("1c449aaab4f509012fa5eaa180fd017eb7724ccacabdffc1c6066d3756dcde5c", hash("sha256", $attachment->content)); + self::assertEquals(53, $attachment->size); + self::assertEquals(3, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/DateTemplateTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/DateTemplateTest.php new file mode 100644 index 000000000..79f42dfe4 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/DateTemplateTest.php @@ -0,0 +1,115 @@ + "2019-04-05 10:10:49", + "04 Jan 2018 10:12:47 UT" => "2018-01-04 10:12:47", + "22 Jun 18 03:56:36 PM -05:00 (GMT -05:00)" => "2018-06-22 20:56:36", + "Sat, 31 Aug 2013 20:08:23 +0580" => "2013-08-31 14:38:23", + "Fri, 1 Feb 2019 01:30:04 +0600 (+06)" => "2019-01-31 19:30:04", + "Mon, 4 Feb 2019 04:03:49 -0300 (-03)" => "2019-02-04 07:03:49", + "Sun, 6 Apr 2008 21:24:33 UT" => "2008-04-06 21:24:33", + "Wed, 11 Sep 2019 15:23:06 +0600 (+06)" => "2019-09-11 09:23:06", + "14 Sep 2019 00:10:08 UT +0200" => "2019-09-14 00:10:08", + "Tue, 08 Nov 2022 18:47:20 +0000 14:03:33 +0000" => "2022-11-08 18:47:20", + "Sat, 10, Dec 2022 09:35:19 +0100" => "2022-12-10 08:35:19", + "Thur, 16 Mar 2023 15:33:07 +0400" => "2023-03-16 11:33:07", + "fr., 25 nov. 2022 06:27:14 +0100/fr., 25 nov. 2022 06:27:14 +0100" => "2022-11-25 05:27:14", + "Di., 15 Feb. 2022 06:52:44 +0100 (MEZ)/Di., 15 Feb. 2022 06:52:44 +0100 (MEZ)" => "2022-02-15 05:52:44", + ]; + + /** + * Test the fixture date-template.eml + * + * @return void + * @throws InvalidMessageDateException + * @throws ReflectionException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + public function testFixture() : void { + try { + $message = $this->getFixture("date-template.eml"); + $this->fail("Expected InvalidMessageDateException"); + } catch (InvalidMessageDateException $e) { + self::assertTrue(true); + } + + self::$manager->setConfig([ + "options" => [ + "fallback_date" => "2021-01-01 00:00:00", + ], + ]); + $message = $this->getFixture("date-template.eml"); + + self::assertEquals("test", $message->subject); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2021-01-01 00:00:00", $message->date->first()->timezone("UTC")->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", (string)$message->from); + self::assertEquals("to@here.com", $message->to); + + self::$manager->setConfig([ + "options" => [ + "fallback_date" => null, + ], + ]); + + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "date-template.eml"]); + $blob = file_get_contents($filename); + self::assertNotFalse($blob); + + foreach ($this->dates as $date => $expected) { + $message = Message::fromString(str_replace("%date_raw_header%", $date, $blob)); + self::assertEquals("test", $message->subject); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals($expected, $message->date->first()->timezone("UTC")->format("Y-m-d H:i:s"), "Date \"$date\" should be \"$expected\""); + self::assertEquals("from@there.com", (string)$message->from); + self::assertEquals("to@here.com", $message->to); + } + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmailAddressTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmailAddressTest.php new file mode 100644 index 000000000..d4e403d7d --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmailAddressTest.php @@ -0,0 +1,39 @@ +getFixture("email_address.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("123@example.com", $message->message_id); + self::assertEquals("Hi\r\nHow are you?", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertFalse($message->date->first()); + self::assertEquals("no_host@UNKNOWN", (string)$message->from); + self::assertEquals("", $message->to); + self::assertEquals("This one: is \"right\" , No-address@UNKNOWN", $message->cc); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailTest.php new file mode 100644 index 000000000..fb6e24922 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailTest.php @@ -0,0 +1,64 @@ +getFixture("embedded_email.eml"); + + self::assertEquals("embedded message", $message->subject); + self::assertEquals([ + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz ; Fri, 29 Jan 2016 14:25:40 +0100', + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz' + ], $message->received->toArray()); + self::assertEquals("7e5798da5747415e5b82fdce042ab2a6@cerstor.cz", $message->message_id); + self::assertEquals("demo@cerstor.cz", $message->return_path); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("Roundcube Webmail/1.0.0", $message->user_agent); + self::assertEquals("email that contains embedded message", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2016-01-29 13:25:40", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("demo@cerstor.cz", $message->from); + self::assertEquals("demo@cerstor.cz", $message->x_sender); + self::assertEquals("demo@cerstor.cz", $message->to); + + $attachments = $message->getAttachments(); + self::assertCount(1, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("demo.eml", $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('eml', $attachment->getExtension()); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("a1f965f10a9872e902a82dde039a237e863f522d238a1cb1968fe3396dbcac65", hash("sha256", $attachment->content)); + self::assertEquals(893, $attachment->size); + self::assertEquals(1, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionEmbeddedTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionEmbeddedTest.php new file mode 100644 index 000000000..7d3fb2d05 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionEmbeddedTest.php @@ -0,0 +1,75 @@ +getFixture("embedded_email_without_content_disposition-embedded.eml"); + + self::assertEquals("embedded_message_subject", $message->subject); + self::assertEquals([ + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz ; Fri, 29 Jan 2016 14:25:40 +0100', + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz' + ], $message->received->toArray()); + self::assertEquals("AC39946EBF5C034B87BABD5343E96979012671D40E38@VM002.cerk.cc", $message->message_id); + self::assertEquals("pl-PL, nl-NL", $message->accept_language); + self::assertEquals("pl-PL", $message->content_language); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("some txt", $message->getTextBody()); + self::assertEquals("\r\n

some txt

\r\n", $message->getHTMLBody()); + + self::assertEquals("2019-04-05 10:10:49", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("demo@cerstor.cz", $message->from); + self::assertEquals("demo@cerstor.cz", $message->to); + + $attachments = $message->getAttachments(); + self::assertCount(2, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("file1.xlsx", $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('xlsx', $attachment->getExtension()); + self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type); + self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content)); + self::assertEquals(40, $attachment->size); + self::assertEquals(3, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("file2.xlsx", $attachment->name); + self::assertEquals('xlsx', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type); + self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content)); + self::assertEquals(40, $attachment->size); + self::assertEquals(4, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php new file mode 100644 index 000000000..603a956d8 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php @@ -0,0 +1,98 @@ +getFixture("embedded_email_without_content_disposition.eml"); + + self::assertEquals("Subject", $message->subject); + self::assertEquals([ + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz ; Fri, 29 Jan 2016 14:25:40 +0100', + 'from webmail.my-office.cz (localhost [127.0.0.1]) by keira.cofis.cz' + ], $message->received->toArray()); + self::assertEquals("AC39946EBF5C034B87BABD5343E96979012671D9F7E4@VM002.cerk.cc", $message->message_id); + self::assertEquals("pl-PL, nl-NL", $message->accept_language); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("TexT\r\n\r\n[cid:file.jpg]", $message->getTextBody()); + self::assertEquals("

TexT

", $message->getHTMLBody()); + + self::assertEquals("2019-04-05 11:48:50", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("demo@cerstor.cz", $message->from); + self::assertEquals("demo@cerstor.cz", $message->to); + + $attachments = $message->getAttachments(); + self::assertCount(4, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("file.jpg", $attachment->name); + self::assertEquals('jpg', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("image/jpeg", $attachment->content_type); + self::assertEquals("6b7fa434f92a8b80aab02d9bf1a12e49ffcae424e4013a1c4f68b67e3d2bbcd0", hash("sha256", $attachment->content)); + self::assertEquals(96, $attachment->size); + self::assertEquals(3, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('a1abc19a', $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('', $attachment->getExtension()); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("2476c8b91a93c6b2fe1bfff593cb55956c2fe8e7ca6de9ad2dc9d101efe7a867", hash("sha256", $attachment->content)); + self::assertEquals(2073, $attachment->size); + self::assertEquals(5, $attachment->part_number); + self::assertNull($attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[2]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("file3.xlsx", $attachment->name); + self::assertEquals('xlsx', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type); + self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content)); + self::assertEquals(40, $attachment->size); + self::assertEquals(6, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[3]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("file4.zip", $attachment->name); + self::assertEquals('zip', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/x-zip-compressed", $attachment->content_type); + self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content)); + self::assertEquals(40, $attachment->size); + self::assertEquals(7, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ExampleBounceTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ExampleBounceTest.php new file mode 100644 index 000000000..d2f418a90 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ExampleBounceTest.php @@ -0,0 +1,99 @@ +getFixture("example_bounce.eml"); + + self::assertEquals("<>", $message->return_path); + self::assertEquals([ + 0 => 'from somewhere.your-server.de by somewhere.your-server.de with LMTP id 3TP8LrElAGSOaAAAmBr1xw (envelope-from <>); Thu, 02 Mar 2023 05:27:29 +0100', + 1 => 'from somewhere06.your-server.de ([1b21:2f8:e0a:50e4::2]) by somewhere.your-server.de with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) id 1pXaXR-0006xQ-BN for demo@foo.de; Thu, 02 Mar 2023 05:27:29 +0100', + 2 => 'from [192.168.0.10] (helo=sslproxy01.your-server.de) by somewhere06.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) id 1pXaXO-000LYP-9R for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 3 => 'from localhost ([127.0.0.1] helo=sslproxy01.your-server.de) by sslproxy01.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) id 1pXaXO-0008gy-7x for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 4 => 'from Debian-exim by sslproxy01.your-server.de with local (Exim 4.92) id 1pXaXO-0008gb-6g for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 5 => 'from somewhere.your-server.de by somewhere.your-server.de with LMTP id 3TP8LrElAGSOaAAAmBr1xw (envelope-from <>)', + ], $message->received->all()); + self::assertEquals("demo@foo.de", $message->envelope_to); + self::assertEquals("Thu, 02 Mar 2023 05:27:29 +0100", $message->delivery_date); + self::assertEquals([ + 0 => 'somewhere.your-server.de; iprev=pass (somewhere06.your-server.de) smtp.remote-ip=1b21:2f8:e0a:50e4::2; spf=none smtp.mailfrom=<>; dmarc=skipped', + 1 => 'somewhere.your-server.de' + ], $message->authentication_results->all()); + self::assertEquals([ + 0 => 'from somewhere.your-server.de by somewhere.your-server.de with LMTP id 3TP8LrElAGSOaAAAmBr1xw (envelope-from <>); Thu, 02 Mar 2023 05:27:29 +0100', + 1 => 'from somewhere06.your-server.de ([1b21:2f8:e0a:50e4::2]) by somewhere.your-server.de with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) id 1pXaXR-0006xQ-BN for demo@foo.de; Thu, 02 Mar 2023 05:27:29 +0100', + 2 => 'from [192.168.0.10] (helo=sslproxy01.your-server.de) by somewhere06.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) id 1pXaXO-000LYP-9R for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 3 => 'from localhost ([127.0.0.1] helo=sslproxy01.your-server.de) by sslproxy01.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) id 1pXaXO-0008gy-7x for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 4 => 'from Debian-exim by sslproxy01.your-server.de with local (Exim 4.92) id 1pXaXO-0008gb-6g for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100', + 5 => 'from somewhere.your-server.de by somewhere.your-server.de with LMTP id 3TP8LrElAGSOaAAAmBr1xw (envelope-from <>)', + ], $message->received->all()); + self::assertEquals("ding@ding.de", $message->x_failed_recipients); + self::assertEquals("auto-replied", $message->auto_submitted); + self::assertEquals("Mail Delivery System ", $message->from); + self::assertEquals("demo@foo.de", $message->to); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("Mail delivery failed", $message->subject); + self::assertEquals("E1pXaXO-0008gb-6g@sslproxy01.your-server.de", $message->message_id); + self::assertEquals("2023-03-02 04:27:26", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("Clear (ClamAV 0.103.8/26827/Wed Mar 1 09:28:49 2023)", $message->x_virus_scanned); + self::assertEquals("0.0 (/)", $message->x_spam_score); + self::assertEquals("bar-demo@foo.de", $message->delivered_to); + self::assertEquals("multipart/report", $message->content_type->last()); + self::assertEquals("5d4847c21c8891e73d62c8246f260a46496958041a499f33ecd47444fdaa591b", hash("sha256", $message->getTextBody())); + self::assertFalse($message->hasHTMLBody()); + + $attachments = $message->attachments(); + self::assertCount(2, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('c541a506', $attachment->filename); + self::assertEquals("c541a506", $attachment->name); + self::assertEquals('', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("message/delivery-status", $attachment->content_type); + self::assertEquals("85ac09d1d74b2d85853084dc22abcad205a6bfde62d6056e3a933ffe7e82e45c", hash("sha256", $attachment->content)); + self::assertEquals(267, $attachment->size); + self::assertEquals(1, $attachment->part_number); + self::assertNull($attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('da786518', $attachment->filename); + self::assertEquals("da786518", $attachment->name); + self::assertEquals('', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("7525331f5fab23ea77f595b995336aca7b8dad12db00ada14abebe7fe5b96e10", hash("sha256", $attachment->content)); + self::assertEquals(776, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertNull($attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FixtureTestCase.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FixtureTestCase.php new file mode 100644 index 000000000..8660bedc0 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FixtureTestCase.php @@ -0,0 +1,93 @@ + [ + "debug" => $_ENV["LIVE_MAILBOX_DEBUG"] ?? false, + ], + 'accounts' => [ + 'default' => [ + 'host' => getenv("LIVE_MAILBOX_HOST"), + 'port' => getenv("LIVE_MAILBOX_PORT"), + 'encryption' => getenv("LIVE_MAILBOX_ENCRYPTION"), + 'validate_cert' => getenv("LIVE_MAILBOX_VALIDATE_CERT"), + 'username' => getenv("LIVE_MAILBOX_USERNAME"), + 'password' => getenv("LIVE_MAILBOX_PASSWORD"), + 'protocol' => 'imap', //might also use imap, [pop3 or nntp (untested)] + ], + ], + ]); + return self::$manager; + } + + /** + * Get a fixture message + * @param string $template + * + * @return Message + * @throws ReflectionException + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + final public function getFixture(string $template) : Message { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", $template]); + $message = Message::fromFile($filename); + self::assertInstanceOf(Message::class, $message); + + return $message; + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FourNestedEmailsTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FourNestedEmailsTest.php new file mode 100644 index 000000000..e6c37ccd7 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/FourNestedEmailsTest.php @@ -0,0 +1,55 @@ +getFixture("four_nested_emails.eml"); + + self::assertEquals("3-third-subject", $message->subject); + self::assertEquals("3-third-content", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertFalse($message->date->first()); + self::assertEquals("test@example.com", $message->from->first()->mail); + self::assertEquals("test@example.com", $message->to->first()->mail); + + $attachments = $message->getAttachments(); + self::assertCount(1, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("2-second-email.eml", $attachment->name); + self::assertEquals('text', $attachment->type); + self::assertEquals('eml', $attachment->getExtension()); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("85012e6a26d064a0288ee62618b3192687385adb4a4e27e48a28f738a325ca46", hash("sha256", $attachment->content)); + self::assertEquals(1376, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/GbkCharsetTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/GbkCharsetTest.php new file mode 100644 index 000000000..7492d9084 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/GbkCharsetTest.php @@ -0,0 +1,37 @@ +getFixture("gbk_charset.eml"); + + self::assertEquals("Nuu", $message->subject); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/HtmlOnlyTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/HtmlOnlyTest.php new file mode 100644 index 000000000..90ef44e35 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/HtmlOnlyTest.php @@ -0,0 +1,37 @@ +getFixture("html_only.eml"); + + self::assertEquals("Nuu", $message->subject); + self::assertEquals("Hi", $message->getHTMLBody()); + self::assertFalse($message->hasTextBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ImapMimeHeaderDecodeReturnsFalseTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ImapMimeHeaderDecodeReturnsFalseTest.php new file mode 100644 index 000000000..7f90a4ec1 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ImapMimeHeaderDecodeReturnsFalseTest.php @@ -0,0 +1,37 @@ +getFixture("imap_mime_header_decode_returns_false.eml"); + + self::assertEquals("=?UTF-8?B?nnDusSNdG92w6Fuw61fMjAxOF8wMy0xMzMyNTMzMTkzLnBkZg==?=", $message->subject->first()); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/InlineAttachmentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/InlineAttachmentTest.php new file mode 100644 index 000000000..edb380cd2 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/InlineAttachmentTest.php @@ -0,0 +1,62 @@ +getFixture("inline_attachment.eml"); + + self::assertEquals("", $message->subject); + self::assertFalse($message->hasTextBody()); + self::assertEquals('', $message->getHTMLBody()); + + self::assertFalse($message->date->first()); + self::assertFalse($message->from->first()); + self::assertFalse($message->to->first()); + + + $attachments = $message->attachments(); + self::assertInstanceOf(AttachmentCollection::class, $attachments); + self::assertCount(1, $attachments); + + $attachment = $attachments[0]; + + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals('d2913999', $attachment->name); + self::assertEquals('d2913999', $attachment->filename); + self::assertEquals('ii_15f0aad691bb745f', $attachment->id); + self::assertEquals('text', $attachment->type); + self::assertEquals('', $attachment->getExtension()); + self::assertEquals("image/png", $attachment->content_type); + self::assertEquals("6568c9e9c35a7fa06f236e89f704d8c9b47183a24f2c978dba6c92e2747e3a13", hash("sha256", $attachment->content)); + self::assertEquals(1486, $attachment->size); + self::assertEquals(1, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertEquals("", $attachment->content_id); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/KsC56011987HeadersTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/KsC56011987HeadersTest.php new file mode 100644 index 000000000..944e9bfb6 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/KsC56011987HeadersTest.php @@ -0,0 +1,46 @@ +getFixture("ks_c_5601-1987_headers.eml"); + + self::assertEquals("RE: 회원님께 Ersi님이 메시지를 보냈습니다.", $message->subject); + self::assertEquals("=?ks_c_5601-1987?B?yLi/+LTUsrIgRXJzabTUwMwguN69w8H2uKYgurizwr3AtM+02S4=?=", $message->thread_topic); + self::assertEquals("1.0", $message->mime_version); + self::assertEquals("Content", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("to@here.com", $message->to->first()->mail); + + + $from = $message->from->first(); + self::assertEquals("김 현진", $from->personal); + self::assertEquals("from", $from->mailbox); + self::assertEquals("there.com", $from->host); + self::assertEquals("from@there.com", $from->mail); + self::assertEquals("김 현진 ", $from->full); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MailThatIsAttachmentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MailThatIsAttachmentTest.php new file mode 100644 index 000000000..0f4164c9e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MailThatIsAttachmentTest.php @@ -0,0 +1,63 @@ +getFixture("mail_that_is_attachment.eml"); + + self::assertEquals("Report domain: yyy.cz Submitter: google.com Report-ID: 2244696771454641389", $message->subject); + self::assertEquals("2244696771454641389@google.com", $message->message_id); + self::assertEquals("1.0", $message->mime_version); + self::assertFalse($message->hasTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2015-02-15 10:21:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("xxx@yyy.cz", $message->to->first()->mail); + self::assertEquals("xxx@yyy.cz", $message->sender->first()->mail); + + $from = $message->from->first(); + self::assertEquals("noreply-dmarc-support via xxx", $from->personal); + self::assertEquals("xxx", $from->mailbox); + self::assertEquals("yyy.cz", $from->host); + self::assertEquals("xxx@yyy.cz", $from->mail); + self::assertEquals("noreply-dmarc-support via xxx ", $from->full); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("google.com!yyy.cz!1423872000!1423958399.zip", $attachment->name); + self::assertEquals('zip', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/zip", $attachment->content_type); + self::assertEquals("c0d4f47b6fde124cea7460c3e509440d1a062705f550b0502b8ba0cbf621c97a", hash("sha256", $attachment->content)); + self::assertEquals(1062, $attachment->size); + self::assertEquals(0, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingDateTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingDateTest.php new file mode 100644 index 000000000..93595adca --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingDateTest.php @@ -0,0 +1,37 @@ +getFixture("missing_date.eml"); + + self::assertEquals("Nuu", $message->getSubject()); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertFalse($message->date->first()); + self::assertEquals("from@here.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingFromTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingFromTest.php new file mode 100644 index 000000000..5d57340cb --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MissingFromTest.php @@ -0,0 +1,37 @@ +getFixture("missing_from.eml"); + + self::assertEquals("Nuu", $message->getSubject()); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertFalse($message->from->first()); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MixedFilenameTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MixedFilenameTest.php new file mode 100644 index 000000000..b2be0e321 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MixedFilenameTest.php @@ -0,0 +1,61 @@ +getFixture("mixed_filename.eml"); + + self::assertEquals("Свежий прайс-лист", $message->subject); + self::assertFalse($message->hasTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2018-02-02 19:23:06", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + + $from = $message->from->first(); + self::assertEquals("Прайсы || ПартКом", $from->personal); + self::assertEquals("support", $from->mailbox); + self::assertEquals("part-kom.ru", $from->host); + self::assertEquals("support@part-kom.ru", $from->mail); + self::assertEquals("Прайсы || ПартКом ", $from->full); + + self::assertEquals("foo@bar.com", $message->to->first()); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("Price4VladDaKar.xlsx", $attachment->name); + self::assertEquals('xlsx', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/octet-stream", $attachment->content_type); + self::assertEquals("b832983842b0ad65db69e4c7096444c540a2393e2d43f70c2c9b8b9fceeedbb1", hash('sha256', $attachment->content)); + self::assertEquals(94, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipartWithoutBodyTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipartWithoutBodyTest.php new file mode 100644 index 000000000..9989b3e75 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipartWithoutBodyTest.php @@ -0,0 +1,63 @@ +getFixture("multipart_without_body.eml"); + + self::assertEquals("This mail will not contain a body", $message->subject); + self::assertEquals("This mail will not contain a body", $message->getTextBody()); + self::assertEquals("d76dfb1ff3231e3efe1675c971ce73f722b906cc049d328db0d255f8d3f65568", hash("sha256", $message->getHTMLBody())); + self::assertEquals("2023-03-11 08:24:31", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("Foo Bülow Bar ", $message->from); + self::assertEquals("some one ", $message->to); + self::assertEquals([ + 0 => 'from AS8PR02MB6805.eurprd02.prod.outlook.com (2603:10a6:20b:252::8) by PA4PR02MB7071.eurprd02.prod.outlook.com with HTTPS; Sat, 11 Mar 2023 08:24:33 +0000', + 1 => 'from omef0ahNgeoJu.eurprd02.prod.outlook.com (2603:10a6:10:33c::12) by AS8PR02MB6805.eurprd02.prod.outlook.com (2603:10a6:20b:252::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.19; Sat, 11 Mar 2023 08:24:31 +0000', + 2 => 'from omef0ahNgeoJu.eurprd02.prod.outlook.com ([fe80::38c0:9c40:7fc6:93a7]) by omef0ahNgeoJu.eurprd02.prod.outlook.com ([fe80::38c0:9c40:7fc6:93a7%7]) with mapi id 15.20.6178.019; Sat, 11 Mar 2023 08:24:31 +0000', + 3 => 'from AS8PR02MB6805.eurprd02.prod.outlook.com (2603:10a6:20b:252::8) by PA4PR02MB7071.eurprd02.prod.outlook.com with HTTPS', + ], $message->received->all()); + self::assertEquals("This mail will not contain a body", $message->thread_topic); + self::assertEquals("AdlT8uVmpHPvImbCRM6E9LODIvAcQA==", $message->thread_index); + self::assertEquals("omef0ahNgeoJuEB51C568ED2227A2DAABB5BB9@omef0ahNgeoJu.eurprd02.prod.outlook.com", $message->message_id); + self::assertEquals("da-DK, en-US", $message->accept_language); + self::assertEquals("en-US", $message->content_language); + self::assertEquals("Internal", $message->x_ms_exchange_organization_authAs); + self::assertEquals("04", $message->x_ms_exchange_organization_authMechanism); + self::assertEquals("omef0ahNgeoJu.eurprd02.prod.outlook.com", $message->x_ms_exchange_organization_authSource); + self::assertEquals("", $message->x_ms_Has_Attach); + self::assertEquals("aa546a02-2b7a-4fb1-7fd4-08db220a09f1", $message->x_ms_exchange_organization_Network_Message_Id); + self::assertEquals("-1", $message->x_ms_exchange_organization_SCL); + self::assertEquals("", $message->x_ms_TNEF_Correlator); + self::assertEquals("0", $message->x_ms_exchange_organization_RecordReviewCfmType); + self::assertEquals("Email", $message->x_ms_publictraffictype); + self::assertEquals("ucf:0;jmr:0;auth:0;dest:I;ENG:(910001)(944506478)(944626604)(920097)(425001)(930097);", $message->X_Microsoft_Antispam_Mailbox_Delivery->first()); + self::assertEquals("0712b5fe22cf6e75fa220501c1a6715a61098983df9e69bad4000c07531c1295", hash("sha256", $message->X_Microsoft_Antispam_Message_Info)); + self::assertEquals("multipart/alternative", $message->Content_Type->last()); + self::assertEquals("1.0", $message->mime_version); + + self::assertCount(0, $message->getAttachments()); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleHtmlPartsAndAttachmentsTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleHtmlPartsAndAttachmentsTest.php new file mode 100644 index 000000000..c08c03e0c --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleHtmlPartsAndAttachmentsTest.php @@ -0,0 +1,76 @@ +getFixture("multiple_html_parts_and_attachments.eml"); + + self::assertEquals("multiple_html_parts_and_attachments", $message->subject); + self::assertEquals("This is the first html part\r\n\r\n\r\n\r\nThis is the second html part\r\n\r\n\r\n\r\nThis is the last html part\r\nhttps://www.there.com", $message->getTextBody()); + self::assertEquals("This is the first html part

\n

This is the second html part

\n

This is the last html part
https://www.there.com



\r\n
", $message->getHTMLBody()); + + self::assertEquals("2023-02-16 09:19:02", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + + $from = $message->from->first(); + self::assertEquals("FromName", $from->personal); + self::assertEquals("from", $from->mailbox); + self::assertEquals("there.com", $from->host); + self::assertEquals("from@there.com", $from->mail); + self::assertEquals("FromName ", $from->full); + + self::assertEquals("to@there.com", $message->to->first()); + + $attachments = $message->attachments(); + self::assertInstanceOf(AttachmentCollection::class, $attachments); + self::assertCount(2, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("attachment1.pdf", $attachment->name); + self::assertEquals('pdf', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/pdf", $attachment->content_type); + self::assertEquals("c162adf19e0f67e26ef0b7f791b33a60b2c23b175560a505dc7f9ec490206e49", hash("sha256", $attachment->content)); + self::assertEquals(4814, $attachment->size); + self::assertEquals(4, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("attachment2.pdf", $attachment->name); + self::assertEquals('pdf', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/pdf", $attachment->content_type); + self::assertEquals("a337b37e9d3edb172a249639919f0eee3d344db352046d15f8f9887e55855a25", hash("sha256", $attachment->content)); + self::assertEquals(5090, $attachment->size); + self::assertEquals(6, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleNestedAttachmentsTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleNestedAttachmentsTest.php new file mode 100644 index 000000000..543c0e21e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/MultipleNestedAttachmentsTest.php @@ -0,0 +1,69 @@ +getFixture("multiple_nested_attachments.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("------------------------------------------------------------------------", $message->getTextBody()); + self::assertEquals("\r\n \r\n\r\n \r\n \r\n \r\n


\r\n

\r\n
\r\n \r\n \r\n  \"\"\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n

\r\n

\r\n
\r\n
\r\n \r\n", $message->getHTMLBody()); + + self::assertEquals("2018-01-15 09:54:09", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertFalse($message->from->first()); + self::assertFalse($message->to->first()); + + $attachments = $message->attachments(); + self::assertInstanceOf(AttachmentCollection::class, $attachments); + self::assertCount(2, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("mleokdgdlgkkecep.png", $attachment->name); + self::assertEquals('png', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("image/png", $attachment->content_type); + self::assertEquals("e0e99b0bd6d5ea3ced99add53cc98b6f8eea6eae8ddd773fd06f3489289385fb", hash("sha256", $attachment->content)); + self::assertEquals(114, $attachment->size); + self::assertEquals(5, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("FF4D00-1.png", $attachment->name); + self::assertEquals('png', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("image/png", $attachment->content_type); + self::assertEquals("e0e99b0bd6d5ea3ced99add53cc98b6f8eea6eae8ddd773fd06f3489289385fb", hash("sha256", $attachment->content)); + self::assertEquals(114, $attachment->size); + self::assertEquals(8, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NestesEmbeddedWithAttachmentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NestesEmbeddedWithAttachmentTest.php new file mode 100644 index 000000000..c5c8c5616 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NestesEmbeddedWithAttachmentTest.php @@ -0,0 +1,69 @@ +getFixture("nestes_embedded_with_attachment.eml"); + + self::assertEquals("Nuu", $message->subject); + self::assertEquals("Dear Sarah", $message->getTextBody()); + self::assertEquals("\r\n\r\n
Dear Sarah,
\r\n", $message->getHTMLBody()); + + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + + $attachments = $message->attachments(); + self::assertInstanceOf(AttachmentCollection::class, $attachments); + self::assertCount(2, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("first.eml", $attachment->name); + self::assertEquals('eml', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("From: from@there.com\r\nTo: to@here.com\r\nSubject: FIRST\r\nDate: Sat, 28 Apr 2018 14:37:16 -0400\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed;\r\n boundary=\"----=_NextPart_000_222_000\"\r\n\r\nThis is a multi-part message in MIME format.\r\n\r\n------=_NextPart_000_222_000\r\nContent-Type: multipart/alternative;\r\n boundary=\"----=_NextPart_000_222_111\"\r\n\r\n\r\n------=_NextPart_000_222_111\r\nContent-Type: text/plain;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nPlease respond directly to this email to update your RMA\r\n\r\n\r\n2018-04-17T11:04:03-04:00\r\n------=_NextPart_000_222_111\r\nContent-Type: text/html;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n\r\n\r\n
Please respond directly to this =\r\nemail to=20\r\nupdate your RMA
\r\n\r\n------=_NextPart_000_222_111--\r\n\r\n------=_NextPart_000_222_000\r\nContent-Type: image/png;\r\n name=\"chrome.png\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n filename=\"chrome.png\"\r\n\r\niVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAB+FBMVEUAAAA/mUPidDHiLi5Cn0Xk\r\nNTPmeUrkdUg/m0Q0pEfcpSbwaVdKskg+lUP4zA/iLi3msSHkOjVAmETdJSjtYFE/lkPnRj3sWUs8\r\nkkLeqCVIq0fxvhXqUkbVmSjwa1n1yBLepyX1xxP0xRXqUkboST9KukpHpUbuvRrzrhF/ljbwalju\r\nZFM4jELaoSdLtElJrUj1xxP6zwzfqSU4i0HYnydMtUlIqUfywxb60AxZqEXaoifgMCXptR9MtklH\r\npEY2iUHWnSjvvRr70QujkC+pUC/90glMuEnlOjVMt0j70QriLS1LtEnnRj3qUUXfIidOjsxAhcZF\r\no0bjNDH0xxNLr0dIrUdmntVTkMoyfL8jcLBRuErhJyrgKyb4zA/5zg3tYFBBmUTmQTnhMinruBzv\r\nvhnxwxZ/st+Ktt5zp9hqota2vtK6y9FemNBblc9HiMiTtMbFtsM6gcPV2r6dwroseLrMrbQrdLGd\r\nyKoobKbo3Zh+ynrgVllZulTsXE3rV0pIqUf42UVUo0JyjEHoS0HmsiHRGR/lmRz/1hjqnxjvpRWf\r\nwtOhusaz0LRGf7FEfbDVmqHXlJeW0pbXq5bec3fX0nTnzmuJuWvhoFFhm0FtrziBsjaAaDCYWC+u\r\nSi6jQS3FsSfLJiTirCOkuCG1KiG+wSC+GBvgyhTszQ64Z77KAAAARXRSTlMAIQRDLyUgCwsE6ebm\r\n5ubg2dLR0byXl4FDQzU1NDEuLSUgC+vr6urq6ubb29vb2tra2tG8vLu7u7uXl5eXgYGBgYGBLiUA\r\nLabIAAABsElEQVQoz12S9VPjQBxHt8VaOA6HE+AOzv1wd7pJk5I2adpCC7RUcHd3d3fXf5PvLkxh\r\neD++z+yb7GSRlwD/+Hj/APQCZWxM5M+goF+RMbHK594v+tPoiN1uHxkt+xzt9+R9wnRTZZQpXQ0T\r\n5uP1IQxToyOAZiQu5HEpjeA4SWIoksRxNiGC1tRZJ4LNxgHgnU5nJZBDvuDdl8lzQRBsQ+s9PZt7\r\ns7Pz8wsL39/DkIfZ4xlB2Gqsq62ta9oxVlVrNZpihFRpGO9fzQw1ms0NDWZz07iGkJmIFH8xxkc3\r\na/WWlubmFkv9AB2SEpDvKxbjidN2faseaNV3zoHXvv7wMODJdkOHAegweAfFPx4G67KluxzottCU\r\n9n8CUqXzcIQdXOytAHqXxomvykhEKN9EFutG22p//0rbNvHVxiJywa8yS2KDfV1dfbu31H8jF1RH\r\niTKtWYeHxUvq3bn0pyjCRaiRU6aDO+gb3aEfEeVNsDgm8zzLy9egPa7Qt8TSJdwhjplk06HH43ZN\r\nJ3s91KKCHQ5x4sw1fRGYDZ0n1L4FKb9/BP5JLYxToheoFCVxz57PPS8UhhEpLBVeAAAAAElFTkSu\r\nQmCC\r\n\r\n------=_NextPart_000_222_000--", $attachment->content); + self::assertEquals(2535, $attachment->size); + self::assertEquals(5, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("second.eml", $attachment->name); + self::assertEquals('eml', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("From: from@there.com\r\nTo: to@here.com\r\nSubject: SECOND\r\nDate: Sat, 28 Apr 2018 13:37:30 -0400\r\nMIME-Version: 1.0\r\nContent-Type: multipart/alternative;\r\n boundary=\"----=_NextPart_000_333_000\"\r\n\r\nThis is a multi-part message in MIME format.\r\n\r\n------=_NextPart_000_333_000\r\nContent-Type: text/plain;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nT whom it may concern:\r\n------=_NextPart_000_333_000\r\nContent-Type: text/html;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n\r\n\r\n
T whom it may concern:
\r\n\r\n\r\n------=_NextPart_000_333_000--", $attachment->content); + self::assertEquals(631, $attachment->size); + self::assertEquals(6, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NullContentCharsetTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NullContentCharsetTest.php new file mode 100644 index 000000000..f8e6c63fb --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/NullContentCharsetTest.php @@ -0,0 +1,39 @@ +getFixture("null_content_charset.eml"); + + self::assertEquals("test", $message->getSubject()); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertEquals("1.0", $message->mime_version); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PecTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PecTest.php new file mode 100644 index 000000000..28ecb27bb --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PecTest.php @@ -0,0 +1,82 @@ +getFixture("pec.eml"); + + self::assertEquals("Certified", $message->subject); + self::assertEquals("Signed", $message->getTextBody()); + self::assertEquals("Signed", $message->getHTMLBody()); + + self::assertEquals("2017-10-02 10:13:43", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("test@example.com", $message->from->first()->mail); + self::assertEquals("test@example.com", $message->to->first()->mail); + + $attachments = $message->attachments(); + + self::assertInstanceOf(AttachmentCollection::class, $attachments); + self::assertCount(3, $attachments); + + $attachment = $attachments[0]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("data.xml", $attachment->name); + self::assertEquals('xml', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/xml", $attachment->content_type); + self::assertEquals("", $attachment->content); + self::assertEquals(8, $attachment->size); + self::assertEquals(4, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[1]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("postacert.eml", $attachment->name); + self::assertEquals('eml', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("message/rfc822", $attachment->content_type); + self::assertEquals("To: test@example.com\r\nFrom: test@example.com\r\nSubject: test-subject\r\nDate: Mon, 2 Oct 2017 12:13:50 +0200\r\nContent-Type: text/plain; charset=iso-8859-15; format=flowed\r\nContent-Transfer-Encoding: 7bit\r\n\r\ntest-content", $attachment->content); + self::assertEquals(216, $attachment->size); + self::assertEquals(5, $attachment->part_number); + self::assertEquals("inline", $attachment->disposition); + self::assertNotEmpty($attachment->id); + + $attachment = $attachments[2]; + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("smime.p7s", $attachment->name); + self::assertEquals('p7s', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("application/x-pkcs7-signature", $attachment->content_type); + self::assertEquals("1", $attachment->content); + self::assertEquals(4, $attachment->size); + self::assertEquals(7, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainOnlyTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainOnlyTest.php new file mode 100644 index 000000000..b3a65bfe9 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainOnlyTest.php @@ -0,0 +1,37 @@ +getFixture("plain_only.eml"); + + self::assertEquals("Nuu", $message->getSubject()); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainTextAttachmentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainTextAttachmentTest.php new file mode 100644 index 000000000..2e9993cc4 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/PlainTextAttachmentTest.php @@ -0,0 +1,54 @@ +getFixture("plain_text_attachment.eml"); + + self::assertEquals("Plain text attachment", $message->subject); + self::assertEquals("Test", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2018-08-21 07:05:14", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("a.txt", $attachment->name); + self::assertEquals('txt', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertNull($attachment->content_type); + self::assertEquals("Hi!", $attachment->content); + self::assertEquals(4, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ReferencesTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ReferencesTest.php new file mode 100644 index 000000000..18473d614 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/ReferencesTest.php @@ -0,0 +1,54 @@ +getFixture("references.eml"); + + self::assertEquals("", $message->subject); + self::assertEquals("Hi\r\nHow are you?", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertFalse($message->date->first()); + + self::assertEquals("b9e87bd5e661a645ed6e3b832828fcc5@example.com", $message->in_reply_to); + self::assertEquals("", $message->from->first()->personal); + self::assertEquals("UNKNOWN", $message->from->first()->host); + self::assertEquals("no_host@UNKNOWN", $message->from->first()->mail); + self::assertFalse($message->to->first()); + + self::assertEquals([ + "231d9ac57aec7d8c1a0eacfeab8af6f3@example.com", + "08F04024-A5B3-4FDE-BF2C-6710DE97D8D9@example.com" + ], $message->getReferences()->all()); + + self::assertEquals([ + 'This one: is "right" ', + 'No-address@UNKNOWN' + ], $message->cc->map(function($address){ + /** @var \Webklex\PHPIMAP\Address $address */ + return $address->full; + })); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/SimpleMultipartTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/SimpleMultipartTest.php new file mode 100644 index 000000000..d2a2d8850 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/SimpleMultipartTest.php @@ -0,0 +1,37 @@ +getFixture("simple_multipart.eml"); + + self::assertEquals("test", $message->getSubject()); + self::assertEquals("MyPlain", $message->getTextBody()); + self::assertEquals("MyHtml", $message->getHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/StructuredWithAttachmentTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/StructuredWithAttachmentTest.php new file mode 100644 index 000000000..3fc591c3e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/StructuredWithAttachmentTest.php @@ -0,0 +1,55 @@ +getFixture("structured_with_attachment.eml"); + + self::assertEquals("Test", $message->getSubject()); + self::assertEquals("Test", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + + self::assertEquals("2017-09-29 08:55:23", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + + self::assertCount(1, $message->attachments()); + + $attachment = $message->attachments()->first(); + self::assertInstanceOf(Attachment::class, $attachment); + self::assertEquals("MyFile.txt", $attachment->name); + self::assertEquals('txt', $attachment->getExtension()); + self::assertEquals('text', $attachment->type); + self::assertEquals("text/plain", $attachment->content_type); + self::assertEquals("MyFileContent", $attachment->content); + self::assertEquals(20, $attachment->size); + self::assertEquals(2, $attachment->part_number); + self::assertEquals("attachment", $attachment->disposition); + self::assertNotEmpty($attachment->id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndefinedCharsetHeaderTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndefinedCharsetHeaderTest.php new file mode 100644 index 000000000..acb3029cd --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndefinedCharsetHeaderTest.php @@ -0,0 +1,59 @@ +getFixture("undefined_charset_header.eml"); + + self::assertEquals("", $message->get("x-real-to")); + self::assertEquals("1.0", $message->get("mime-version")); + self::assertEquals("Mon, 27 Feb 2017 13:21:44 +0930", $message->get("Resent-Date")); + self::assertEquals("", $message->get("Resent-From")); + self::assertEquals("BlaBla", $message->get("X-Stored-In")); + self::assertEquals("", $message->get("Return-Path")); + self::assertEquals([ + 'from by bla.bla (CommuniGate Pro RULE 6.1.13) with RULE id 14057804; Mon, 27 Feb 2017 13:21:44 +0930', + 'from by bla.bla (CommuniGate Pro RULE 6.1.13) with RULE id 14057804' + ], $message->get("Received")->all()); + self::assertEquals(")", $message->getHTMLBody()); + self::assertFalse($message->hasTextBody()); + self::assertEquals("2017-02-27 03:51:29", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + + $from = $message->from->first(); + self::assertInstanceOf(Address::class, $from); + + self::assertEquals("myGov", $from->personal); + self::assertEquals("info", $from->mailbox); + self::assertEquals("bla.bla", $from->host); + self::assertEquals("info@bla.bla", $from->mail); + self::assertEquals("myGov ", $from->full); + + self::assertEquals("sales@bla.bla", $message->to->first()->mail); + self::assertEquals("Submit your tax refund | Australian Taxation Office.", $message->subject); + self::assertEquals("201702270351.BGF77614@bla.bla", $message->message_id); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsMinusTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsMinusTest.php new file mode 100644 index 000000000..f9ee7999f --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsMinusTest.php @@ -0,0 +1,42 @@ +getFixture("undisclosed_recipients_minus.eml"); + + self::assertEquals("test", $message->subject); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from); + self::assertEquals([ + "undisclosed-recipients", + "" + ], $message->to->map(function ($item) { + return $item->mailbox; + })); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsSpaceTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsSpaceTest.php new file mode 100644 index 000000000..b86321eb9 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsSpaceTest.php @@ -0,0 +1,42 @@ +getFixture("undisclosed_recipients_space.eml"); + + self::assertEquals("test", $message->subject); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from); + self::assertEquals([ + "Undisclosed recipients", + "" + ], $message->to->map(function ($item) { + return $item->mailbox; + })); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsTest.php new file mode 100644 index 000000000..f5f441644 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UndisclosedRecipientsTest.php @@ -0,0 +1,42 @@ +getFixture("undisclosed_recipients.eml"); + + self::assertEquals("test", $message->subject); + self::assertEquals("Hi!", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from); + self::assertEquals([ + "Undisclosed Recipients", + "" + ], $message->to->map(function ($item) { + return $item->mailbox; + })); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UnknownEncodingTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UnknownEncodingTest.php new file mode 100644 index 000000000..3a570cbdd --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/UnknownEncodingTest.php @@ -0,0 +1,37 @@ +getFixture("unknown_encoding.eml"); + + self::assertEquals("test", $message->getSubject()); + self::assertEquals("MyPlain", $message->getTextBody()); + self::assertEquals("MyHtml", $message->getHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetPlainOnlyTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetPlainOnlyTest.php new file mode 100644 index 000000000..497334d51 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetPlainOnlyTest.php @@ -0,0 +1,37 @@ +getFixture("without_charset_plain_only.eml"); + + self::assertEquals("Nuu", $message->getSubject()); + self::assertEquals("Hi", $message->getTextBody()); + self::assertFalse($message->hasHTMLBody()); + self::assertEquals("2017-09-13 11:05:45", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetSimpleMultipartTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetSimpleMultipartTest.php new file mode 100644 index 000000000..2a9ea2a02 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/fixtures/WithoutCharsetSimpleMultipartTest.php @@ -0,0 +1,37 @@ +getFixture("without_charset_simple_multipart.eml"); + + self::assertEquals("test", $message->getSubject()); + self::assertEquals("MyPlain", $message->getTextBody()); + self::assertEquals("MyHtml", $message->getHTMLBody()); + self::assertEquals("2017-09-27 10:48:51", $message->date->first()->setTimezone('UTC')->format("Y-m-d H:i:s")); + self::assertEquals("from@there.com", $message->from->first()->mail); + self::assertEquals("to@here.com", $message->to->first()->mail); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue275Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue275Test.php new file mode 100644 index 000000000..4049998d9 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue275Test.php @@ -0,0 +1,38 @@ +subject); + self::assertSame("Asdf testing123 this is a body", $message->getTextBody()); + } + + public function testIssueEmail2() { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "issue-275-2.eml"]); + $message = Message::fromFile($filename); + + $body = "Test\r\n\r\nMed venlig hilsen\r\nMartin Larsen\r\nFeline Holidays A/S\r\nTlf 78 77 04 12"; + + self::assertSame("Test 1017", (string)$message->subject); + self::assertSame($body, $message->getTextBody()); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue355Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue355Test.php new file mode 100644 index 000000000..a61cd07aa --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue355Test.php @@ -0,0 +1,29 @@ +get("subject"); + + $this->assertEquals("Re: Uppdaterat ärende (447899), kostnader för hjälp med stadgeändring enligt ny lagstiftning", $subject->toString()); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue379Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue379Test.php new file mode 100644 index 000000000..99b679218 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue379Test.php @@ -0,0 +1,61 @@ +getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + $this->assertEquals(214, $message->getSize()); + + // Clean up + $this->assertTrue($message->delete(true)); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue382Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue382Test.php new file mode 100644 index 000000000..4e6388277 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue382Test.php @@ -0,0 +1,33 @@ +from->first(); + + self::assertSame("Mail Delivery System", $from->personal); + self::assertSame("MAILER-DAEMON", $from->mailbox); + self::assertSame("mta-09.someserver.com", $from->host); + self::assertSame("MAILER-DAEMON@mta-09.someserver.com", $from->mail); + self::assertSame("Mail Delivery System ", $from->full); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue383Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue383Test.php new file mode 100644 index 000000000..0f20a396f --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue383Test.php @@ -0,0 +1,69 @@ +getClient(); + $client->connect(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'Entwürfe+']); + + $folder = $client->getFolder($folder_path); + $this->deleteFolder($folder); + + $folder = $client->createFolder($folder_path, false); + self::assertInstanceOf(Folder::class, $folder); + + $folder = $this->getFolder($folder_path); + self::assertInstanceOf(Folder::class, $folder); + + $this->assertEquals('Entwürfe+', $folder->name); + $this->assertEquals($folder_path, $folder->full_name); + + $folder_path = implode($delimiter, ['INBOX', 'Entw&APw-rfe+']); + $this->assertEquals($folder_path, $folder->path); + + // Clean up + if ($this->deleteFolder($folder) === false) { + $this->fail("Could not delete folder: " . $folder->path); + } + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue393Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue393Test.php new file mode 100644 index 000000000..73099e076 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue393Test.php @@ -0,0 +1,62 @@ +getClient(); + $client->connect(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $pattern = implode($delimiter, ['doesnt_exist', '%']); + + $folder = $client->getFolder('doesnt_exist'); + $this->deleteFolder($folder); + + $folders = $client->getFolders(true, $pattern, true); + self::assertCount(0, $folders); + + try { + $client->getFolders(true, $pattern, false); + $this->fail('Expected FolderFetchingException::class exception not thrown'); + } catch (FolderFetchingException $e) { + self::assertInstanceOf(FolderFetchingException::class, $e); + } + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue401Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue401Test.php new file mode 100644 index 000000000..e250a5508 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue401Test.php @@ -0,0 +1,27 @@ +subject); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue407Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue407Test.php new file mode 100644 index 000000000..4adcbb399 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue407Test.php @@ -0,0 +1,57 @@ +getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + self::assertInstanceOf(Message::class, $message); + + $message->setFlag("Seen"); + + $flags = $this->getClient()->getConnection()->flags($message->uid, IMAP::ST_UID)->validatedData(); + + self::assertIsArray($flags); + self::assertSame(1, count($flags)); + self::assertSame("\\Seen", $flags[$message->uid][0]); + + $message->delete(); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue410Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue410Test.php new file mode 100644 index 000000000..d02724ca7 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue410Test.php @@ -0,0 +1,52 @@ +subject); + + $attachments = $message->getAttachments(); + + self::assertSame(1, $attachments->count()); + + $attachment = $attachments->first(); + self::assertSame("☆第132号 「ガーデン&エクステリア」専門店のためのQ&Aサロン 【月刊エクステリア・ワーク】", $attachment->filename); + self::assertSame("☆第132号 「ガーデン&エクステリア」専門店のためのQ&Aサロン 【月刊エクステリア・ワーク】", $attachment->name); + } + + public function testIssueEmailB() { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "issue-410b.eml"]); + $message = Message::fromFile($filename); + + self::assertSame("386 - 400021804 - 19., Heiligenstädter Straße 80 - 0819306 - Anfrage Vergabevorschlag", (string)$message->subject); + + $attachments = $message->getAttachments(); + + self::assertSame(1, $attachments->count()); + + $attachment = $attachments->first(); + self::assertSame("2021_Mängelliste_0819306.xlsx", $attachment->description); + self::assertSame("2021_Mängelliste_0819306.xlsx", $attachment->filename); + self::assertSame("2021_Mängelliste_0819306.xlsx", $attachment->name); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue412Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue412Test.php new file mode 100644 index 000000000..5d1055410 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue412Test.php @@ -0,0 +1,30 @@ +subject); + self::assertSame("64254d63e92a36ee02c760676351e60a", md5($message->getTextBody())); + self::assertSame("2e4de288f6a1ed658548ed11fcdb1d79", md5($message->getHTMLBody())); + self::assertSame(0, $message->attachments()->count()); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue413Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue413Test.php new file mode 100644 index 000000000..cfdae5483 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue413Test.php @@ -0,0 +1,81 @@ +getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + /** @var Message $message */ + $_message = $this->appendMessageTemplate($folder, 'issue-413.eml'); + + $message = $folder->messages()->getMessageByMsgn($_message->msgn); + self::assertEquals($message->uid, $_message->uid); + + self::assertSame("Test Message", (string)$message->subject); + self::assertSame("This is just a test, so ignore it (if you can!)\r\n\r\nTony Marston", $message->getTextBody()); + + $message->delete(); + } + + /** + * Static parsing test + * + * @return void + * @throws \ReflectionException + * @throws \Webklex\PHPIMAP\Exceptions\AuthFailedException + * @throws \Webklex\PHPIMAP\Exceptions\ConnectionFailedException + * @throws \Webklex\PHPIMAP\Exceptions\ImapBadRequestException + * @throws \Webklex\PHPIMAP\Exceptions\ImapServerErrorException + * @throws \Webklex\PHPIMAP\Exceptions\InvalidMessageDateException + * @throws \Webklex\PHPIMAP\Exceptions\MaskNotFoundException + * @throws \Webklex\PHPIMAP\Exceptions\MessageContentFetchingException + * @throws \Webklex\PHPIMAP\Exceptions\ResponseException + * @throws \Webklex\PHPIMAP\Exceptions\RuntimeException + */ + public function testIssueEmail() { + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "issue-413.eml"]); + $message = Message::fromFile($filename); + + self::assertSame("Test Message", (string)$message->subject); + self::assertSame("This is just a test, so ignore it (if you can!)\r\n\r\nTony Marston", $message->getTextBody()); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue414Test.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue414Test.php new file mode 100644 index 000000000..36a1d3001 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/issues/Issue414Test.php @@ -0,0 +1,43 @@ +subject); + + $attachments = $message->getAttachments(); + + self::assertSame(2, $attachments->count()); + + $attachment = $attachments->first(); + self::assertEmpty($attachment->description); + self::assertSame("exampleMyFile.txt", $attachment->filename); + self::assertSame("exampleMyFile.txt", $attachment->name); + self::assertSame("be62f7e6", $attachment->id); + + $attachment = $attachments->last(); + self::assertEmpty($attachment->description); + self::assertSame("phpfoo", $attachment->filename); + self::assertSame("phpfoo", $attachment->name); + self::assertSame("12e1d38b", $attachment->hash); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/ClientTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/ClientTest.php new file mode 100644 index 000000000..307894a7a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/ClientTest.php @@ -0,0 +1,318 @@ +getClient()->connect()); + } + + /** + * Test if the connection is working + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testIsConnected(): void { + $client = $this->getClient()->connect(); + + self::assertTrue($client->isConnected()); + } + + /** + * Test if the connection state can be determined + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testDisconnect(): void { + $client = $this->getClient()->connect(); + + self::assertFalse($client->disconnect()->isConnected()); + } + + /** + * Test to get the default inbox folder + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws FolderFetchingException + */ + public function testGetFolder(): void { + $client = $this->getClient()->connect(); + + $folder = $client->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + } + + /** + * Test to get the default inbox folder by name + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFolderByName(): void { + $client = $this->getClient()->connect(); + + $folder = $client->getFolderByName('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + } + + /** + * Test to get the default inbox folder by path + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFolderByPath(): void { + $client = $this->getClient()->connect(); + + $folder = $client->getFolderByPath('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + } + + /** + * Test to get all folders + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFolders(): void { + $client = $this->getClient()->connect(); + + $folders = $client->getFolders(false); + self::assertTrue($folders->count() > 0); + } + + public function testGetFoldersWithStatus(): void { + $client = $this->getClient()->connect(); + + $folders = $client->getFoldersWithStatus(false); + self::assertTrue($folders->count() > 0); + } + + public function testOpenFolder(): void { + $client = $this->getClient()->connect(); + + $status = $client->openFolder("INBOX"); + self::assertTrue(isset($status["flags"]) && count($status["flags"]) > 0); + self::assertTrue(($status["uidnext"] ?? 0) > 0); + self::assertTrue(($status["uidvalidity"] ?? 0) > 0); + self::assertTrue(($status["recent"] ?? -1) >= 0); + self::assertTrue(($status["exists"] ?? -1) >= 0); + } + + public function testCreateFolder(): void { + $client = $this->getClient()->connect(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', $this->getSpecialChars()]); + + $folder = $client->getFolder($folder_path); + + $this->deleteFolder($folder); + + $folder = $client->createFolder($folder_path, false); + self::assertInstanceOf(Folder::class, $folder); + + $folder = $this->getFolder($folder_path); + self::assertInstanceOf(Folder::class, $folder); + + $this->assertEquals($this->getSpecialChars(), $folder->name); + $this->assertEquals($folder_path, $folder->full_name); + + $folder_path = implode($delimiter, ['INBOX', EncodingAliases::convert($this->getSpecialChars(), "utf-8", "utf7-imap")]); + $this->assertEquals($folder_path, $folder->path); + + // Clean up + if ($this->deleteFolder($folder) === false) { + $this->fail("Could not delete folder: " . $folder->path); + } + } + + public function testCheckFolder(): void { + $client = $this->getClient()->connect(); + + $status = $client->checkFolder("INBOX"); + self::assertTrue(isset($status["flags"]) && count($status["flags"]) > 0); + self::assertTrue(($status["uidnext"] ?? 0) > 0); + self::assertTrue(($status["uidvalidity"] ?? 0) > 0); + self::assertTrue(($status["recent"] ?? -1) >= 0); + self::assertTrue(($status["exists"] ?? -1) >= 0); + } + + public function testGetFolderPath(): void { + $client = $this->getClient()->connect(); + + self::assertIsArray($client->openFolder("INBOX")); + self::assertEquals("INBOX", $client->getFolderPath()); + } + + public function testId(): void { + $client = $this->getClient()->connect(); + + $info = $client->Id(); + self::assertIsArray($info); + $valid = false; + foreach ($info as $value) { + if (str_starts_with($value, "OK")) { + $valid = true; + break; + } + } + self::assertTrue($valid); + } + + public function testGetQuotaRoot(): void { + if (!getenv("LIVE_MAILBOX_QUOTA_SUPPORT")) { + $this->markTestSkipped("Quota support is not enabled"); + } + + $client = $this->getClient()->connect(); + + $quota = $client->getQuotaRoot("INBOX"); + self::assertIsArray($quota); + self::assertTrue(count($quota) > 1); + self::assertIsArray($quota[0]); + self::assertEquals("INBOX", $quota[0][1]); + self::assertIsArray($quota[1]); + self::assertIsArray($quota[1][2]); + self::assertTrue($quota[1][2][2] > 0); + } + + public function testSetTimeout(): void { + $client = $this->getClient()->connect(); + + self::assertInstanceOf(ProtocolInterface::class, $client->setTimeout(57)); + self::assertEquals(57, $client->getTimeout()); + } + + public function testExpunge(): void { + $client = $this->getClient()->connect(); + + $client->openFolder("INBOX"); + $status = $client->expunge(); + + self::assertIsArray($status); + self::assertIsArray($status[0]); + self::assertEquals("OK", $status[0][0]); + } + + public function testGetDefaultMessageMask(): void { + $client = $this->getClient(); + + self::assertEquals(MessageMask::class, $client->getDefaultMessageMask()); + } + + public function testGetDefaultEvents(): void { + $client = $this->getClient(); + + self::assertIsArray($client->getDefaultEvents("message")); + } + + public function testSetDefaultMessageMask(): void { + $client = $this->getClient(); + + self::assertInstanceOf(Client::class, $client->setDefaultMessageMask(AttachmentMask::class)); + self::assertEquals(AttachmentMask::class, $client->getDefaultMessageMask()); + + $client->setDefaultMessageMask(MessageMask::class); + } + + public function testGetDefaultAttachmentMask(): void { + $client = $this->getClient(); + + self::assertEquals(AttachmentMask::class, $client->getDefaultAttachmentMask()); + } + + public function testSetDefaultAttachmentMask(): void { + $client = $this->getClient(); + + self::assertInstanceOf(Client::class, $client->setDefaultAttachmentMask(MessageMask::class)); + self::assertEquals(MessageMask::class, $client->getDefaultAttachmentMask()); + + $client->setDefaultAttachmentMask(AttachmentMask::class); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/FolderTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/FolderTest.php new file mode 100644 index 000000000..78da70170 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/FolderTest.php @@ -0,0 +1,422 @@ +getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + self::assertInstanceOf(WhereQuery::class, $folder->query()); + self::assertInstanceOf(WhereQuery::class, $folder->search()); + self::assertInstanceOf(WhereQuery::class, $folder->messages()); + } + + /** + * Test Folder::hasChildren() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws EventNotFoundException + */ + public function testHasChildren(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $delimiter = $this->getManager()->get("options.delimiter"); + $child_path = implode($delimiter, ['INBOX', 'test']); + if ($folder->getClient()->getFolder($child_path) === null) { + $folder->getClient()->createFolder($child_path, false); + $folder = $this->getFolder('INBOX'); + } + + self::assertTrue($folder->hasChildren()); + } + + /** + * Test Folder::setChildren() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetChildren(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $delimiter = $this->getManager()->get("options.delimiter"); + $child_path = implode($delimiter, ['INBOX', 'test']); + if ($folder->getClient()->getFolder($child_path) === null) { + $folder->getClient()->createFolder($child_path, false); + $folder = $this->getFolder('INBOX'); + } + self::assertTrue($folder->hasChildren()); + + $folder->setChildren(new FolderCollection()); + self::assertTrue($folder->getChildren()->isEmpty()); + } + + /** + * Test Folder::getChildren() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetChildren(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $delimiter = $this->getManager()->get("options.delimiter"); + $child_path = implode($delimiter, ['INBOX', 'test']); + if ($folder->getClient()->getFolder($child_path) === null) { + $folder->getClient()->createFolder($child_path, false); + } + + $folder = $folder->getClient()->getFolders()->where('name', 'INBOX')->first(); + self::assertInstanceOf(Folder::class, $folder); + + self::assertTrue($folder->hasChildren()); + self::assertFalse($folder->getChildren()->isEmpty()); + } + + /** + * Test Folder::move() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testMove(): void { + $client = $this->getClient(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'test']); + + $folder = $client->getFolder($folder_path); + if ($folder === null) { + $folder = $client->createFolder($folder_path, false); + } + $new_folder_path = implode($delimiter, ['INBOX', 'other']); + $new_folder = $client->getFolder($new_folder_path); + $new_folder?->delete(false); + + $status = $folder->move($new_folder_path, false); + self::assertIsArray($status); + self::assertTrue(str_starts_with($status[0], 'OK')); + + $new_folder = $client->getFolder($new_folder_path); + self::assertEquals($new_folder_path, $new_folder->path); + self::assertEquals('other', $new_folder->name); + + if ($this->deleteFolder($new_folder) === false) { + $this->fail("Could not delete folder: " . $new_folder->path); + } + } + + /** + * Test Folder::delete() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testDelete(): void { + $client = $this->getClient(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'test']); + + $folder = $client->getFolder($folder_path); + if ($folder === null) { + $folder = $client->createFolder($folder_path, false); + } + self::assertInstanceOf(Folder::class, $folder); + + if ($this->deleteFolder($folder) === false) { + $this->fail("Could not delete folder: " . $folder->path); + } + } + + /** + * Test Folder::overview() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + */ + public function testOverview(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $folder->select(); + + // Test empty overview + $overview = $folder->overview(); + self::assertIsArray($overview); + self::assertCount(0, $overview); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + + $overview = $folder->overview(); + + self::assertIsArray($overview); + self::assertCount(1, $overview); + + self::assertEquals($message->from->first()->full, end($overview)["from"]->toString()); + + self::assertTrue($message->delete()); + } + + /** + * Test Folder::appendMessage() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testAppendMessage(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals("Example", $message->subject); + self::assertEquals("to@someone-else.com", $message->to); + self::assertEquals("from@someone.com", $message->from); + + // Clean up + $this->assertTrue($message->delete(true)); + } + + /** + * Test Folder::subscribe() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSubscribe(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $status = $folder->subscribe(); + self::assertIsArray($status); + self::assertTrue(str_starts_with($status[0], 'OK')); + + // Clean up + $folder->unsubscribe(); + } + + /** + * Test Folder::unsubscribe() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testUnsubscribe(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $folder->subscribe(); + + $status = $folder->subscribe(); + self::assertIsArray($status); + self::assertTrue(str_starts_with($status[0], 'OK')); + } + + /** + * Test Folder::examine() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testExamine(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $status = $folder->examine(); + self::assertTrue(isset($status["flags"]) && count($status["flags"]) > 0); + self::assertTrue(($status["uidnext"] ?? 0) > 0); + self::assertTrue(($status["uidvalidity"] ?? 0) > 0); + self::assertTrue(($status["recent"] ?? -1) >= 0); + self::assertTrue(($status["exists"] ?? -1) >= 0); + } + + /** + * Test Folder::getClient() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetClient(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + self::assertInstanceOf(Client::class, $folder->getClient()); + } + + /** + * Test Folder::setDelimiter() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetDelimiter(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $folder->setDelimiter("/"); + self::assertEquals("/", $folder->delimiter); + + $folder->setDelimiter("."); + self::assertEquals(".", $folder->delimiter); + + $default_delimiter = $this->getManager()->get("options.delimiter", "/"); + $folder->setDelimiter(null); + self::assertEquals($default_delimiter, $folder->delimiter); + } + +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LegacyTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LegacyTest.php new file mode 100644 index 000000000..85fa44481 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LegacyTest.php @@ -0,0 +1,475 @@ +markTestSkipped("This test requires a live mailbox. Please set the LIVE_MAILBOX environment variable to run this test."); + } + + parent::__construct($name, $data, $dataName); + $manager = new ClientManager([ + 'options' => [ + "debug" => $_ENV["LIVE_MAILBOX_DEBUG"] ?? false, + ], + 'accounts' => [ + 'legacy' => [ + 'host' => getenv("LIVE_MAILBOX_HOST"), + 'port' => getenv("LIVE_MAILBOX_PORT"), + 'encryption' => getenv("LIVE_MAILBOX_ENCRYPTION"), + 'validate_cert' => getenv("LIVE_MAILBOX_VALIDATE_CERT"), + 'username' => getenv("LIVE_MAILBOX_USERNAME"), + 'password' => getenv("LIVE_MAILBOX_PASSWORD"), + 'protocol' => 'legacy-imap', + ], + ], + ]); + self::$client = $manager->account('legacy'); + self::$client->connect(); + self::assertInstanceOf(Client::class, self::$client->connect()); + } + + /** + * @throws RuntimeException + * @throws MessageFlagException + * @throws MessageContentFetchingException + * @throws ResponseException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ConnectionFailedException + * @throws InvalidMessageDateException + * @throws AuthFailedException + * @throws MessageHeaderFetchingException + */ + public function testSizes(): void { + + $delimiter = ClientManager::get("options.delimiter"); + $child_path = implode($delimiter, ['INBOX', 'test']); + if (self::$client->getFolder($child_path) === null) { + self::$client->createFolder($child_path, false); + } + $folder = $this->getFolder($child_path); + + self::assertInstanceOf(Folder::class, $folder); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals(214, $message->size); + self::assertEquals(214, self::$client->getConnection()->sizes($message->uid)->array()[$message->uid]); + } + + /** + * Try to create a new query instance + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testQuery(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + self::assertInstanceOf(WhereQuery::class, $folder->query()); + self::assertInstanceOf(WhereQuery::class, $folder->search()); + self::assertInstanceOf(WhereQuery::class, $folder->messages()); + } + + /** + * Get a folder + * @param string $folder_path + * + * @return Folder + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws FolderFetchingException + */ + final protected function getFolder(string $folder_path = "INDEX"): Folder { + $folder = self::$client->getFolderByPath($folder_path); + self::assertInstanceOf(Folder::class, $folder); + + return $folder; + } + + + /** + * Append a message to a folder + * @param Folder $folder + * @param string $message + * + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function appendMessage(Folder $folder, string $message): Message { + $status = $folder->select(); + if (!isset($status['uidnext'])) { + $this->fail("No UIDNEXT returned"); + } + + $response = $folder->appendMessage($message); + $valid_response = false; + foreach ($response as $line) { + if (str_starts_with($line, 'OK')) { + $valid_response = true; + break; + } + } + if (!$valid_response) { + $this->fail("Failed to append message: ".implode("\n", $response)); + } + + $message = $folder->messages()->getMessageByUid($status['uidnext']); + self::assertInstanceOf(Message::class, $message); + + return $message; + } + + /** + * Append a message template to a folder + * @param Folder $folder + * @param string $template + * + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function appendMessageTemplate(Folder $folder, string $template): Message { + $content = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", $template])); + return $this->appendMessage($folder, $content); + } + + /** + * Delete a folder if it is given + * @param Folder|null $folder + * + * @return bool + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function deleteFolder(Folder $folder = null): bool { + $response = $folder?->delete(false); + if (is_array($response)) { + $valid_response = false; + foreach ($response as $line) { + if (str_starts_with($line, 'OK')) { + $valid_response = true; + break; + } + } + if (!$valid_response) { + $this->fail("Failed to delete mailbox: ".implode("\n", $response)); + } + return $valid_response; + } + return false; + } + + /** + * Try to create a new query instance with a where clause + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + * @throws GetMessagesFailedException + * @throws InvalidWhereQueryCriteriaException + * @throws MessageSearchValidationException + */ + public function testQueryWhere(): void { + $delimiter = ClientManager::get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'search']); + + $folder = self::$client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = self::$client->createFolder($folder_path, false); + + $messages = [ + $this->appendMessageTemplate($folder, '1366671050@github.com.eml'), + $this->appendMessageTemplate($folder, 'attachment_encoded_filename.eml'), + $this->appendMessageTemplate($folder, 'attachment_long_filename.eml'), + $this->appendMessageTemplate($folder, 'attachment_no_disposition.eml'), + $this->appendMessageTemplate($folder, 'bcc.eml'), + $this->appendMessageTemplate($folder, 'boolean_decoded_content.eml'), + $this->appendMessageTemplate($folder, 'email_address.eml'), + $this->appendMessageTemplate($folder, 'embedded_email.eml'), + $this->appendMessageTemplate($folder, 'embedded_email_without_content_disposition.eml'), + $this->appendMessageTemplate($folder, 'embedded_email_without_content_disposition-embedded.eml'), + $this->appendMessageTemplate($folder, 'example_attachment.eml'), + $this->appendMessageTemplate($folder, 'example_bounce.eml'), + $this->appendMessageTemplate($folder, 'four_nested_emails.eml'), + $this->appendMessageTemplate($folder, 'gbk_charset.eml'), + $this->appendMessageTemplate($folder, 'html_only.eml'), + $this->appendMessageTemplate($folder, 'imap_mime_header_decode_returns_false.eml'), + $this->appendMessageTemplate($folder, 'inline_attachment.eml'), + $this->appendMessageTemplate($folder, 'issue-275.eml'), + $this->appendMessageTemplate($folder, 'issue-275-2.eml'), + $this->appendMessageTemplate($folder, 'issue-348.eml'), + $this->appendMessageTemplate($folder, 'ks_c_5601-1987_headers.eml'), + $this->appendMessageTemplate($folder, 'mail_that_is_attachment.eml'), + $this->appendMessageTemplate($folder, 'missing_date.eml'), + $this->appendMessageTemplate($folder, 'missing_from.eml'), + $this->appendMessageTemplate($folder, 'mixed_filename.eml'), + $this->appendMessageTemplate($folder, 'multipart_without_body.eml'), + $this->appendMessageTemplate($folder, 'multiple_html_parts_and_attachments.eml'), + $this->appendMessageTemplate($folder, 'multiple_nested_attachments.eml'), + $this->appendMessageTemplate($folder, 'nestes_embedded_with_attachment.eml'), + $this->appendMessageTemplate($folder, 'null_content_charset.eml'), + $this->appendMessageTemplate($folder, 'pec.eml'), + $this->appendMessageTemplate($folder, 'plain.eml'), + $this->appendMessageTemplate($folder, 'plain_only.eml'), + $this->appendMessageTemplate($folder, 'plain_text_attachment.eml'), + $this->appendMessageTemplate($folder, 'references.eml'), + $this->appendMessageTemplate($folder, 'simple_multipart.eml'), + $this->appendMessageTemplate($folder, 'structured_with_attachment.eml'), + $this->appendMessageTemplate($folder, 'thread_my_topic.eml'), + $this->appendMessageTemplate($folder, 'thread_re_my_topic.eml'), + $this->appendMessageTemplate($folder, 'thread_unrelated.eml'), + $this->appendMessageTemplate($folder, 'undefined_charset_header.eml'), + $this->appendMessageTemplate($folder, 'undisclosed_recipients_minus.eml'), + $this->appendMessageTemplate($folder, 'undisclosed_recipients_space.eml'), + $this->appendMessageTemplate($folder, 'unknown_encoding.eml'), + $this->appendMessageTemplate($folder, 'without_charset_plain_only.eml'), + $this->appendMessageTemplate($folder, 'without_charset_simple_multipart.eml'), + ]; + + $folder->getClient()->expunge(); + + $query = $folder->query()->all(); + self::assertEquals(count($messages), $query->count()); + + $query = $folder->query()->whereSubject("test"); + self::assertEquals(11, $query->count()); + + $query = $folder->query()->whereOn(Carbon::now()); + self::assertEquals(count($messages), $query->count()); + + self::assertTrue($this->deleteFolder($folder)); + } + + /** + * Test query where criteria + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testQueryWhereCriteria(): void { + self::$client->reconnect(); + + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $this->assertWhereSearchCriteria($folder, 'SUBJECT', 'Test'); + $this->assertWhereSearchCriteria($folder, 'BODY', 'Test'); + $this->assertWhereSearchCriteria($folder, 'TEXT', 'Test'); + $this->assertWhereSearchCriteria($folder, 'KEYWORD', 'Test'); + $this->assertWhereSearchCriteria($folder, 'UNKEYWORD', 'Test'); + $this->assertWhereSearchCriteria($folder, 'FLAGGED', 'Seen'); + $this->assertWhereSearchCriteria($folder, 'UNFLAGGED', 'Seen'); + $this->assertHeaderSearchCriteria($folder, 'Message-ID', 'Seen'); + $this->assertHeaderSearchCriteria($folder, 'In-Reply-To', 'Seen'); + $this->assertWhereSearchCriteria($folder, 'BCC', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'CC', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'FROM', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'TO', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'UID', '1'); + $this->assertWhereSearchCriteria($folder, 'UID', '1,2'); + $this->assertWhereSearchCriteria($folder, 'ALL'); + $this->assertWhereSearchCriteria($folder, 'NEW'); + $this->assertWhereSearchCriteria($folder, 'OLD'); + $this->assertWhereSearchCriteria($folder, 'SEEN'); + $this->assertWhereSearchCriteria($folder, 'UNSEEN'); + $this->assertWhereSearchCriteria($folder, 'RECENT'); + $this->assertWhereSearchCriteria($folder, 'ANSWERED'); + $this->assertWhereSearchCriteria($folder, 'UNANSWERED'); + $this->assertWhereSearchCriteria($folder, 'DELETED'); + $this->assertWhereSearchCriteria($folder, 'UNDELETED'); + $this->assertHeaderSearchCriteria($folder, 'Content-Language','en_US'); + $this->assertWhereSearchCriteria($folder, 'CUSTOM X-Spam-Flag NO'); + $this->assertWhereSearchCriteria($folder, 'CUSTOM X-Spam-Flag YES'); + $this->assertWhereSearchCriteria($folder, 'NOT'); + $this->assertWhereSearchCriteria($folder, 'OR'); + $this->assertWhereSearchCriteria($folder, 'AND'); + $this->assertWhereSearchCriteria($folder, 'BEFORE', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'BEFORE', Carbon::now()->subDays(1), true); + $this->assertWhereSearchCriteria($folder, 'ON', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'ON', Carbon::now()->subDays(1), true); + $this->assertWhereSearchCriteria($folder, 'SINCE', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'SINCE', Carbon::now()->subDays(1), true); + } + + /** + * Assert where search criteria + * @param Folder $folder + * @param string $criteria + * @param string|Carbon|null $value + * @param bool $date + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws ResponseException + * @throws RuntimeException + */ + protected function assertWhereSearchCriteria(Folder $folder, string $criteria, Carbon|string $value = null, bool $date = false): void { + $query = $folder->query()->where($criteria, $value); + self::assertInstanceOf(WhereQuery::class, $query); + + $item = $query->getQuery()->first(); + $criteria = str_replace("CUSTOM ", "", $criteria); + $expected = $value === null ? [$criteria] : [$criteria, $value]; + if ($date === true && $value instanceof Carbon) { + $date_format = ClientManager::get('date_format', 'd M y'); + $expected[1] = $value->format($date_format); + } + + self::assertIsArray($item); + self::assertIsString($item[0]); + if($value !== null) { + self::assertCount(2, $item); + self::assertIsString($item[1]); + }else{ + self::assertCount(1, $item); + } + self::assertSame($expected, $item); + } + + /** + * Assert header search criteria + * @param Folder $folder + * @param string $criteria + * @param mixed|null $value + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws ResponseException + * @throws RuntimeException + */ + protected function assertHeaderSearchCriteria(Folder $folder, string $criteria, mixed $value = null): void { + $query = $folder->query()->whereHeader($criteria, $value); + self::assertInstanceOf(WhereQuery::class, $query); + + $item = $query->getQuery()->first(); + + self::assertIsArray($item); + self::assertIsString($item[0]); + self::assertCount(1, $item); + self::assertSame(['HEADER '.$criteria.' '.$value], $item); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LiveMailboxTestCase.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LiveMailboxTestCase.php new file mode 100644 index 000000000..c59e67739 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/LiveMailboxTestCase.php @@ -0,0 +1,220 @@ +-@#[]_ß_б_π_€_✔_你_يد_Z_'; + + /** + * Client manager + * @var ClientManager $manager + */ + protected static ClientManager $manager; + + /** + * Get the client manager + * + * @return ClientManager + */ + final protected function getManager(): ClientManager { + if (!isset(self::$manager)) { + self::$manager = new ClientManager([ + 'options' => [ + "debug" => $_ENV["LIVE_MAILBOX_DEBUG"] ?? false, + ], + 'accounts' => [ + 'default' => [ + 'host' => getenv("LIVE_MAILBOX_HOST"), + 'port' => getenv("LIVE_MAILBOX_PORT"), + 'encryption' => getenv("LIVE_MAILBOX_ENCRYPTION"), + 'validate_cert' => getenv("LIVE_MAILBOX_VALIDATE_CERT"), + 'username' => getenv("LIVE_MAILBOX_USERNAME"), + 'password' => getenv("LIVE_MAILBOX_PASSWORD"), + 'protocol' => 'imap', //might also use imap, [pop3 or nntp (untested)] + ], + ], + ]); + } + return self::$manager; + } + + /** + * Get the client + * + * @return Client + * @throws MaskNotFoundException + */ + final protected function getClient(): Client { + if (!getenv("LIVE_MAILBOX") ?? false) { + $this->markTestSkipped("This test requires a live mailbox. Please set the LIVE_MAILBOX environment variable to run this test."); + } + return $this->getManager()->account('default'); + } + + /** + * Get special chars + * + * @return string + */ + final protected function getSpecialChars(): string { + return self::SPECIAL_CHARS; + } + + /** + * Get a folder + * @param string $folder_path + * + * @return Folder + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws FolderFetchingException + */ + final protected function getFolder(string $folder_path = "INDEX"): Folder { + $client = $this->getClient(); + self::assertInstanceOf(Client::class, $client->connect()); + + $folder = $client->getFolderByPath($folder_path); + self::assertInstanceOf(Folder::class, $folder); + + return $folder; + } + + /** + * Append a message to a folder + * @param Folder $folder + * @param string $message + * + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function appendMessage(Folder $folder, string $message): Message { + $status = $folder->select(); + if (!isset($status['uidnext'])) { + $this->fail("No UIDNEXT returned"); + } + + $response = $folder->appendMessage($message); + $valid_response = false; + foreach ($response as $line) { + if (str_starts_with($line, 'OK')) { + $valid_response = true; + break; + } + } + if (!$valid_response) { + $this->fail("Failed to append message: ".implode("\n", $response)); + } + + $message = $folder->messages()->getMessageByUid($status['uidnext']); + self::assertInstanceOf(Message::class, $message); + + return $message; + } + + /** + * Append a message template to a folder + * @param Folder $folder + * @param string $template + * + * @return Message + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function appendMessageTemplate(Folder $folder, string $template): Message { + $content = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", $template])); + return $this->appendMessage($folder, $content); + } + + /** + * Delete a folder if it is given + * @param Folder|null $folder + * + * @return bool + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws ResponseException + * @throws RuntimeException + */ + final protected function deleteFolder(Folder $folder = null): bool { + $response = $folder?->delete(false); + if (is_array($response)) { + $valid_response = false; + foreach ($response as $line) { + if (str_starts_with($line, 'OK')) { + $valid_response = true; + break; + } + } + if (!$valid_response) { + $this->fail("Failed to delete mailbox: ".implode("\n", $response)); + } + return $valid_response; + } + return false; + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/MessageTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/MessageTest.php new file mode 100644 index 000000000..31b155794 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/MessageTest.php @@ -0,0 +1,2410 @@ +getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + self::assertInstanceOf(Message::class, $message); + + return $message; + } + + /** + * Test Message::convertEncoding() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + * @throws MessageNotFoundException + */ + public function testConvertEncoding(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("Entwürfe+", $message->convertEncoding("Entw&APw-rfe+", "UTF7-IMAP", "UTF-8")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::thread() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws GetMessagesFailedException + */ + public function testThread(): void { + $client = $this->getClient(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'thread']); + + $folder = $client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = $client->createFolder($folder_path, false); + + $message1 = $this->appendMessageTemplate($folder, "thread_my_topic.eml"); + $message2 = $this->appendMessageTemplate($folder, "thread_re_my_topic.eml"); + $message3 = $this->appendMessageTemplate($folder, "thread_unrelated.eml"); + + $thread = $message1->thread($folder); + self::assertCount(2, $thread); + + $thread = $message2->thread($folder); + self::assertCount(2, $thread); + + $thread = $message3->thread($folder); + self::assertCount(1, $thread); + + // Cleanup + self::assertTrue($message1->delete()); + self::assertTrue($message2->delete()); + self::assertTrue($message3->delete()); + $client->expunge(); + + self::assertTrue($this->deleteFolder($folder)); + } + + /** + * Test Message::hasAttachments() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testHasAttachments(): void { + $message = $this->getDefaultMessage(); + self::assertFalse($message->hasAttachments()); + + $folder = $message->getFolder(); + self::assertInstanceOf(Folder::class, $folder); + self::assertTrue($message->delete()); + + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertInstanceOf(Message::class, $message); + self::assertTrue($message->hasAttachments()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFetchOptions() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFetchOptions(): void { + $message = $this->getDefaultMessage(); + self::assertEquals(IMAP::FT_PEEK, $message->getFetchOptions()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getMessageId() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetMessageId(): void { + $folder = $this->getFolder('INBOX'); + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals("d3a5e91963cb805cee975687d5acb1c6@swift.generated", $message->getMessageId()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getReplyTo() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetReplyTo(): void { + $folder = $this->getFolder('INBOX'); + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals("testreply_to ", $message->getReplyTo()); + self::assertEquals("someone@domain.tld", $message->getReplyTo()->first()->mail); + self::assertEquals("testreply_to", $message->getReplyTo()->first()->personal); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setSequence() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetSequence(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + + $message->setSequence(IMAP::ST_MSGN); + self::assertEquals($message->msgn, $message->getSequenceId()); + + $message->setSequence(null); + self::assertEquals($message->uid, $message->getSequenceId()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getEvent() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetEvent(): void { + $message = $this->getDefaultMessage(); + + $message->setEvent("message", "test", "test"); + self::assertEquals("test", $message->getEvent("message", "test")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::__construct() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function test__construct(): void { + $message = $this->getDefaultMessage(); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFlag() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFlag(): void { + $message = $this->getDefaultMessage(); + + self::assertTrue($message->setFlag("seen")); + self::assertTrue($message->getFlags()->has("seen")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getMsgn() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetMsgn(): void { + $client = $this->getClient(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'test']); + + $folder = $client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = $client->createFolder($folder_path, false); + + $message = $this->appendMessageTemplate($folder, "plain.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals(1, $message->getMsgn()); + + // Cleanup + self::assertTrue($message->delete()); + self::assertTrue($this->deleteFolder($folder)); + } + + /** + * Test Message::peek() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testPeek(): void { + $message = $this->getDefaultMessage(); + self::assertFalse($message->getFlags()->has("seen")); + self::assertEquals(IMAP::FT_PEEK, $message->getFetchOptions()); + $message->peek(); + self::assertFalse($message->getFlags()->has("seen")); + + $message->setFetchOption(IMAP::FT_UID); + self::assertEquals(IMAP::FT_UID, $message->getFetchOptions()); + $message->peek(); + self::assertTrue($message->getFlags()->has("seen")); + + // Cleanup + self::assertTrue($message->delete()); + + } + + /** + * Test Message::unsetFlag() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testUnsetFlag(): void { + $message = $this->getDefaultMessage(); + + self::assertFalse($message->getFlags()->has("seen")); + + self::assertTrue($message->setFlag("seen")); + self::assertTrue($message->getFlags()->has("seen")); + + self::assertTrue($message->unsetFlag("seen")); + self::assertFalse($message->getFlags()->has("seen")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setSequenceId() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetSequenceId(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + + $original_sequence = $message->getSequenceId(); + + $message->setSequenceId(1, IMAP::ST_MSGN); + self::assertEquals(1, $message->getSequenceId()); + + $message->setSequenceId(1); + self::assertEquals(1, $message->getSequenceId()); + + $message->setSequenceId($original_sequence); + + // Cleanup + self::assertTrue($message->delete()); + + } + + /** + * Test Message::getTo() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetTo(): void { + $message = $this->getDefaultMessage(); + $folder = $message->getFolder(); + self::assertInstanceOf(Folder::class, $folder); + + self::assertEquals("to@someone-else.com", $message->getTo()); + self::assertTrue($message->delete()); + + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertInstanceOf(Message::class, $message); + + self::assertEquals("testnameto ", $message->getTo()); + self::assertEquals("testnameto", $message->getTo()->first()->personal); + self::assertEquals("someone@domain.tld", $message->getTo()->first()->mail); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setUid() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetUid(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + + $original_sequence = $message->getSequenceId(); + + $message->setUid(789); + self::assertEquals(789, $message->uid); + + $message->setUid($original_sequence); + + // Cleanup + self::assertTrue($message->delete()); + + } + + /** + * Test Message::getUid() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetUid(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + + $original_sequence = $message->uid; + + $message->setUid(789); + self::assertEquals(789, $message->uid); + self::assertEquals(789, $message->getUid()); + + $message->setUid($original_sequence); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::hasTextBody() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testHasTextBody(): void { + $message = $this->getDefaultMessage(); + self::assertTrue($message->hasTextBody()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::__get() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function test__get(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + self::assertEquals("Example", $message->subject); + self::assertEquals("to@someone-else.com", $message->to); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getDate() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetDate(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(Carbon::class, $message->getDate()->toDate()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setMask() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetMask(): void { + $message = $this->getDefaultMessage(); + self::assertEquals(MessageMask::class, $message->getMask()); + + $message->setMask(AttachmentMask::class); + self::assertEquals(AttachmentMask::class, $message->getMask()); + + $message->setMask(MessageMask::class); + self::assertEquals(MessageMask::class, $message->getMask()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getSequenceId() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetSequenceId(): void { + $message = $this->getDefaultMessage(); + self::assertEquals($message->uid, $message->getSequenceId()); + + $original_sequence = $message->getSequenceId(); + + $message->setSequenceId(789, IMAP::ST_MSGN); + self::assertEquals(789, $message->getSequenceId()); + + $message->setSequenceId(789); + self::assertEquals(789, $message->getSequenceId()); + + $message->setSequenceId($original_sequence); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setConfig() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetConfig(): void { + $message = $this->getDefaultMessage(); + + $config = $message->getConfig(); + self::assertIsArray($config); + + $message->setConfig(["foo" => "bar"]); + self::assertArrayHasKey("foo", $message->getConfig()); + + $message->setConfig($config); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getEvents() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetEvents(): void { + $message = $this->getDefaultMessage(); + + $events = $message->getEvents(); + self::assertIsArray($events); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFetchOption() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFetchOption(): void { + $message = $this->getDefaultMessage(); + + $fetch_option = $message->fetch_options; + + $message->setFetchOption(IMAP::FT_UID); + self::assertEquals(IMAP::FT_UID, $message->fetch_options); + + $message->setFetchOption(IMAP::FT_PEEK); + self::assertEquals(IMAP::FT_PEEK, $message->fetch_options); + + $message->setFetchOption(IMAP::FT_UID | IMAP::FT_PEEK); + self::assertEquals(IMAP::FT_UID | IMAP::FT_PEEK, $message->fetch_options); + + $message->setFetchOption($fetch_option); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getMsglist() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetMsglist(): void { + $message = $this->getDefaultMessage(); + + self::assertEquals(0, (int)$message->getMsglist()->toString()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::decodeString() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testDecodeString(): void { + $message = $this->getDefaultMessage(); + + $string = '

Test

'; + self::assertEquals('

Test

', $message->decodeString($string, IMAP::MESSAGE_ENC_QUOTED_PRINTABLE)); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::attachments() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testAttachments(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertTrue($message->hasAttachments()); + self::assertSameSize([1], $message->attachments()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getMask() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetMask(): void { + $message = $this->getDefaultMessage(); + self::assertEquals(MessageMask::class, $message->getMask()); + + $message->setMask(AttachmentMask::class); + self::assertEquals(AttachmentMask::class, $message->getMask()); + + $message->setMask(MessageMask::class); + self::assertEquals(MessageMask::class, $message->getMask()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::hasHTMLBody() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testHasHTMLBody(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "1366671050@github.com.eml"); + self::assertTrue($message->hasHTMLBody()); + + // Cleanup + self::assertTrue($message->delete()); + + $message = $this->getDefaultMessage(); + self::assertFalse($message->hasHTMLBody()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setEvents() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetEvents(): void { + $message = $this->getDefaultMessage(); + + $events = $message->getEvents(); + self::assertIsArray($events); + + $message->setEvents(["foo" => "bar"]); + self::assertArrayHasKey("foo", $message->getEvents()); + + $message->setEvents($events); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::__set() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function test__set(): void { + $message = $this->getDefaultMessage(); + + $message->foo = "bar"; + self::assertEquals("bar", $message->getFoo()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getHTMLBody() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetHTMLBody(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "1366671050@github.com.eml"); + self::assertTrue($message->hasHTMLBody()); + self::assertIsString($message->getHTMLBody()); + + // Cleanup + self::assertTrue($message->delete()); + + $message = $this->getDefaultMessage(); + self::assertFalse($message->hasHTMLBody()); + self::assertEmpty($message->getHTMLBody()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getSequence() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetSequence(): void { + $message = $this->getDefaultMessage(); + self::assertEquals(IMAP::ST_UID, $message->getSequence()); + + $original_sequence = $message->getSequence(); + + $message->setSequence(IMAP::ST_MSGN); + self::assertEquals(IMAP::ST_MSGN, $message->getSequence()); + + $message->setSequence($original_sequence); + self::assertEquals(IMAP::ST_UID, $message->getSequence()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::restore() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testRestore(): void { + $message = $this->getDefaultMessage(); + + $message->setFlag("deleted"); + self::assertTrue($message->hasFlag("deleted")); + + $message->restore(); + self::assertFalse($message->hasFlag("deleted")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getPriority() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetPriority(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertEquals(1, $message->getPriority()->first()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setAttachments() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetAttachments(): void { + $message = $this->getDefaultMessage(); + + $message->setAttachments(new AttachmentCollection(["foo" => "bar"])); + self::assertIsArray($message->attachments()->toArray()); + self::assertTrue($message->attachments()->has("foo")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFrom() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFrom(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("from@someone.com", $message->getFrom()->first()->mail); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setEvent() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetEvent(): void { + $message = $this->getDefaultMessage(); + + $message->setEvent("message", "bar", "foo"); + self::assertArrayHasKey("bar", $message->getEvents()["message"]); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getInReplyTo() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetInReplyTo(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("", $message->getInReplyTo()); + + // Cleanup + self::assertTrue($message->delete()); + + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "1366671050@github.com.eml"); + self::assertEquals("Webklex/php-imap/issues/349@github.com", $message->getInReplyTo()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::copy() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testCopy(): void { + $message = $this->getDefaultMessage(); + $client = $message->getClient(); + self::assertInstanceOf(Client::class, $client); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'test']); + + $folder = $client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = $client->createFolder($folder_path, false); + self::assertInstanceOf(Folder::class, $folder); + + $new_message = $message->copy($folder->path, true); + self::assertInstanceOf(Message::class, $new_message); + self::assertEquals($folder->path, $new_message->getFolder()->path); + + // Cleanup + self::assertTrue($message->delete()); + self::assertTrue($new_message->delete()); + + } + + /** + * Test Message::getBodies() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetBodies(): void { + $message = $this->getDefaultMessage(); + self::assertIsArray($message->getBodies()); + self::assertCount(1, $message->getBodies()); + + // Cleanup + self::assertTrue($message->delete()); + + } + + /** + * Test Message::getFlags() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFlags(): void { + $message = $this->getDefaultMessage(); + self::assertIsArray($message->getFlags()->all()); + + self::assertFalse($message->hasFlag("seen")); + + self::assertTrue($message->setFlag("seen")); + self::assertTrue($message->getFlags()->has("seen")); + self::assertTrue($message->hasFlag("seen")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::addFlag() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testAddFlag(): void { + $message = $this->getDefaultMessage(); + self::assertFalse($message->hasFlag("seen")); + + self::assertTrue($message->addFlag("seen")); + self::assertTrue($message->hasFlag("seen")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getSubject() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetSubject(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("Example", $message->getSubject()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getClient() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetClient(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(Client::class, $message->getClient()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFetchFlagsOption() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFetchFlagsOption(): void { + $message = $this->getDefaultMessage(); + + self::assertTrue($message->getFetchFlagsOption()); + $message->setFetchFlagsOption(false); + self::assertFalse($message->getFetchFlagsOption()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::mask() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testMask(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(MessageMask::class, $message->mask()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setMsglist() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetMsglist(): void { + $message = $this->getDefaultMessage(); + $message->setMsglist("foo"); + self::assertEquals("foo", $message->getMsglist()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::flags() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testFlags(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(FlagCollection::class, $message->flags()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getAttributes() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetAttributes(): void { + $message = $this->getDefaultMessage(); + self::assertIsArray($message->getAttributes()); + self::assertArrayHasKey("subject", $message->getAttributes()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getAttachments() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetAttachments(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(AttachmentCollection::class, $message->getAttachments()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getRawBody() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetRawBody(): void { + $message = $this->getDefaultMessage(); + self::assertIsString($message->getRawBody()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::is() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testIs(): void { + $message = $this->getDefaultMessage(); + self::assertTrue($message->is($message)); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFlags() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFlags(): void { + $message = $this->getDefaultMessage(); + $message->setFlags(new FlagCollection()); + self::assertFalse($message->hasFlag("recent")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::make() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws ResponseException + * @throws RuntimeException + * @throws ReflectionException + */ + public function testMake(): void { + $folder = $this->getFolder('INBOX'); + $folder->getClient()->openFolder($folder->path); + + $email = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "1366671050@github.com.eml"])); + if(!str_contains($email, "\r\n")){ + $email = str_replace("\n", "\r\n", $email); + } + + $raw_header = substr($email, 0, strpos($email, "\r\n\r\n")); + $raw_body = substr($email, strlen($raw_header)+8); + + $message = Message::make(0, null, $folder->getClient(), $raw_header, $raw_body, [0 => "\\Seen"], IMAP::ST_UID); + self::assertInstanceOf(Message::class, $message); + } + + /** + * Test Message::setAvailableFlags() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetAvailableFlags(): void { + $message = $this->getDefaultMessage(); + + $message->setAvailableFlags(["foo"]); + self::assertSameSize(["foo"], $message->getAvailableFlags()); + self::assertEquals("foo", $message->getAvailableFlags()[0]); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getSender() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetSender(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "example_attachment.eml"); + self::assertEquals("testsender ", $message->getSender()); + self::assertEquals("testsender", $message->getSender()->first()->personal); + self::assertEquals("someone@domain.tld", $message->getSender()->first()->mail); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::fromFile() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws ReflectionException + * @throws ResponseException + * @throws RuntimeException + */ + public function testFromFile(): void { + $this->getManager(); + $filename = implode(DIRECTORY_SEPARATOR, [__DIR__, "..", "messages", "1366671050@github.com.eml"]); + $message = Message::fromFile($filename); + self::assertInstanceOf(Message::class, $message); + } + + /** + * Test Message::getStructure() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetStructure(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(Structure::class, $message->getStructure()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::get() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + * @throws MessageSizeFetchingException + */ + public function testGet(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("Example", $message->get("subject")); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getSize() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetSize(): void { + $message = $this->getDefaultMessage(); + self::assertEquals(214, $message->getSize()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getHeader() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetHeader(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(Header::class, $message->getHeader()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getReferences() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetReferences(): void { + $folder = $this->getFolder('INBOX'); + + $message = $this->appendMessageTemplate($folder, "1366671050@github.com.eml"); + self::assertIsArray($message->getReferences()->all()); + self::assertEquals("Webklex/php-imap/issues/349@github.com", $message->getReferences()->first()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFolderPath() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFolderPath(): void { + $message = $this->getDefaultMessage(); + + $folder_path = $message->getFolderPath(); + + $message->setFolderPath("foo"); + self::assertEquals("foo", $message->getFolderPath()); + + $message->setFolderPath($folder_path); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getTextBody() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetTextBody(): void { + $message = $this->getDefaultMessage(); + self::assertIsString($message->getTextBody()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::move() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testMove(): void { + $message = $this->getDefaultMessage(); + $client = $message->getClient(); + self::assertInstanceOf(Client::class, $client); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'test']); + + $folder = $client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = $client->createFolder($folder_path, false); + self::assertInstanceOf(Folder::class, $folder); + + $message = $message->move($folder->path, true); + self::assertInstanceOf(Message::class, $message); + self::assertEquals($folder->path, $message->getFolder()->path); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFolderPath() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFolderPath(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("INBOX", $message->getFolderPath()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFolder() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFolder(): void { + $message = $this->getDefaultMessage(); + self::assertInstanceOf(Folder::class, $message->getFolder()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFetchBodyOption() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFetchBodyOption(): void { + $message = $this->getDefaultMessage(); + self::assertTrue($message->getFetchBodyOption()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setFetchBodyOption() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetFetchBodyOption(): void { + $message = $this->getDefaultMessage(); + + $message->setFetchBodyOption(false); + self::assertFalse($message->getFetchBodyOption()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::getFetchFlagsOption() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testGetFetchFlagsOption(): void { + $message = $this->getDefaultMessage(); + self::assertTrue($message->getFetchFlagsOption()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::__call() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function test__call(): void { + $message = $this->getDefaultMessage(); + self::assertEquals("Example", $message->getSubject()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setClient() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetClient(): void { + $message = $this->getDefaultMessage(); + $client = $message->getClient(); + self::assertInstanceOf(Client::class, $client); + + $message->setClient(null); + self::assertNull($message->getClient()); + + $message->setClient($client); + self::assertInstanceOf(Client::class, $message->getClient()); + + // Cleanup + self::assertTrue($message->delete()); + } + + /** + * Test Message::setMsgn() + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws MessageNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testSetMsgn(): void { + $message = $this->getDefaultMessage(); + + $uid = $message->getUid(); + $message->setMsgn(789); + self::assertEquals(789, $message->getMsgn()); + $message->setUid($uid); + + // Cleanup + self::assertTrue($message->delete()); + } +} diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/QueryTest.php b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/QueryTest.php new file mode 100644 index 000000000..af651ef41 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/live/QueryTest.php @@ -0,0 +1,283 @@ +getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + self::assertInstanceOf(WhereQuery::class, $folder->query()); + self::assertInstanceOf(WhereQuery::class, $folder->search()); + self::assertInstanceOf(WhereQuery::class, $folder->messages()); + } + + /** + * Try to create a new query instance with a where clause + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws EventNotFoundException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidMessageDateException + * @throws MaskNotFoundException + * @throws MessageContentFetchingException + * @throws MessageFlagException + * @throws MessageHeaderFetchingException + * @throws ResponseException + * @throws RuntimeException + * @throws GetMessagesFailedException + * @throws InvalidWhereQueryCriteriaException + * @throws MessageSearchValidationException + */ + public function testQueryWhere(): void { + $client = $this->getClient(); + + $delimiter = $this->getManager()->get("options.delimiter"); + $folder_path = implode($delimiter, ['INBOX', 'search']); + + $folder = $client->getFolder($folder_path); + if ($folder !== null) { + self::assertTrue($this->deleteFolder($folder)); + } + $folder = $client->createFolder($folder_path, false); + + $messages = [ + $this->appendMessageTemplate($folder, '1366671050@github.com.eml'), + $this->appendMessageTemplate($folder, 'attachment_encoded_filename.eml'), + $this->appendMessageTemplate($folder, 'attachment_long_filename.eml'), + $this->appendMessageTemplate($folder, 'attachment_no_disposition.eml'), + $this->appendMessageTemplate($folder, 'bcc.eml'), + $this->appendMessageTemplate($folder, 'boolean_decoded_content.eml'), + $this->appendMessageTemplate($folder, 'email_address.eml'), + $this->appendMessageTemplate($folder, 'embedded_email.eml'), + $this->appendMessageTemplate($folder, 'embedded_email_without_content_disposition.eml'), + $this->appendMessageTemplate($folder, 'embedded_email_without_content_disposition-embedded.eml'), + $this->appendMessageTemplate($folder, 'example_attachment.eml'), + $this->appendMessageTemplate($folder, 'example_bounce.eml'), + $this->appendMessageTemplate($folder, 'four_nested_emails.eml'), + $this->appendMessageTemplate($folder, 'gbk_charset.eml'), + $this->appendMessageTemplate($folder, 'html_only.eml'), + $this->appendMessageTemplate($folder, 'imap_mime_header_decode_returns_false.eml'), + $this->appendMessageTemplate($folder, 'inline_attachment.eml'), + $this->appendMessageTemplate($folder, 'issue-275.eml'), + $this->appendMessageTemplate($folder, 'issue-275-2.eml'), + $this->appendMessageTemplate($folder, 'issue-348.eml'), + $this->appendMessageTemplate($folder, 'ks_c_5601-1987_headers.eml'), + $this->appendMessageTemplate($folder, 'mail_that_is_attachment.eml'), + $this->appendMessageTemplate($folder, 'missing_date.eml'), + $this->appendMessageTemplate($folder, 'missing_from.eml'), + $this->appendMessageTemplate($folder, 'mixed_filename.eml'), + $this->appendMessageTemplate($folder, 'multipart_without_body.eml'), + $this->appendMessageTemplate($folder, 'multiple_html_parts_and_attachments.eml'), + $this->appendMessageTemplate($folder, 'multiple_nested_attachments.eml'), + $this->appendMessageTemplate($folder, 'nestes_embedded_with_attachment.eml'), + $this->appendMessageTemplate($folder, 'null_content_charset.eml'), + $this->appendMessageTemplate($folder, 'pec.eml'), + $this->appendMessageTemplate($folder, 'plain.eml'), + $this->appendMessageTemplate($folder, 'plain_only.eml'), + $this->appendMessageTemplate($folder, 'plain_text_attachment.eml'), + $this->appendMessageTemplate($folder, 'references.eml'), + $this->appendMessageTemplate($folder, 'simple_multipart.eml'), + $this->appendMessageTemplate($folder, 'structured_with_attachment.eml'), + $this->appendMessageTemplate($folder, 'thread_my_topic.eml'), + $this->appendMessageTemplate($folder, 'thread_re_my_topic.eml'), + $this->appendMessageTemplate($folder, 'thread_unrelated.eml'), + $this->appendMessageTemplate($folder, 'undefined_charset_header.eml'), + $this->appendMessageTemplate($folder, 'undisclosed_recipients_minus.eml'), + $this->appendMessageTemplate($folder, 'undisclosed_recipients_space.eml'), + $this->appendMessageTemplate($folder, 'unknown_encoding.eml'), + $this->appendMessageTemplate($folder, 'without_charset_plain_only.eml'), + $this->appendMessageTemplate($folder, 'without_charset_simple_multipart.eml'), + ]; + + $folder->getClient()->expunge(); + + $query = $folder->query()->all(); + self::assertEquals(count($messages), $query->count()); + + $query = $folder->query()->whereSubject("test"); + self::assertEquals(11, $query->count()); + + $query = $folder->query()->whereOn(Carbon::now()); + self::assertEquals(count($messages), $query->count()); + + self::assertTrue($this->deleteFolder($folder)); + } + + /** + * Test query where criteria + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws FolderFetchingException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws MaskNotFoundException + * @throws ResponseException + * @throws RuntimeException + */ + public function testQueryWhereCriteria(): void { + $folder = $this->getFolder('INBOX'); + self::assertInstanceOf(Folder::class, $folder); + + $this->assertWhereSearchCriteria($folder, 'SUBJECT', 'Test'); + $this->assertWhereSearchCriteria($folder, 'BODY', 'Test'); + $this->assertWhereSearchCriteria($folder, 'TEXT', 'Test'); + $this->assertWhereSearchCriteria($folder, 'KEYWORD', 'Test'); + $this->assertWhereSearchCriteria($folder, 'UNKEYWORD', 'Test'); + $this->assertWhereSearchCriteria($folder, 'FLAGGED', 'Seen'); + $this->assertWhereSearchCriteria($folder, 'UNFLAGGED', 'Seen'); + $this->assertHeaderSearchCriteria($folder, 'Message-ID', 'Seen'); + $this->assertHeaderSearchCriteria($folder, 'In-Reply-To', 'Seen'); + $this->assertWhereSearchCriteria($folder, 'BCC', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'CC', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'FROM', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'TO', 'test@example.com'); + $this->assertWhereSearchCriteria($folder, 'UID', '1'); + $this->assertWhereSearchCriteria($folder, 'UID', '1,2'); + $this->assertWhereSearchCriteria($folder, 'ALL'); + $this->assertWhereSearchCriteria($folder, 'NEW'); + $this->assertWhereSearchCriteria($folder, 'OLD'); + $this->assertWhereSearchCriteria($folder, 'SEEN'); + $this->assertWhereSearchCriteria($folder, 'UNSEEN'); + $this->assertWhereSearchCriteria($folder, 'RECENT'); + $this->assertWhereSearchCriteria($folder, 'ANSWERED'); + $this->assertWhereSearchCriteria($folder, 'UNANSWERED'); + $this->assertWhereSearchCriteria($folder, 'DELETED'); + $this->assertWhereSearchCriteria($folder, 'UNDELETED'); + $this->assertHeaderSearchCriteria($folder, 'Content-Language','en_US'); + $this->assertWhereSearchCriteria($folder, 'CUSTOM X-Spam-Flag NO'); + $this->assertWhereSearchCriteria($folder, 'CUSTOM X-Spam-Flag YES'); + $this->assertWhereSearchCriteria($folder, 'NOT'); + $this->assertWhereSearchCriteria($folder, 'OR'); + $this->assertWhereSearchCriteria($folder, 'AND'); + $this->assertWhereSearchCriteria($folder, 'BEFORE', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'BEFORE', Carbon::now()->subDays(1), true); + $this->assertWhereSearchCriteria($folder, 'ON', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'ON', Carbon::now()->subDays(1), true); + $this->assertWhereSearchCriteria($folder, 'SINCE', '01-Jan-2020', true); + $this->assertWhereSearchCriteria($folder, 'SINCE', Carbon::now()->subDays(1), true); + } + + /** + * Assert where search criteria + * @param Folder $folder + * @param string $criteria + * @param string|Carbon|null $value + * @param bool $date + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws ResponseException + * @throws RuntimeException + */ + protected function assertWhereSearchCriteria(Folder $folder, string $criteria, Carbon|string $value = null, bool $date = false): void { + $query = $folder->query()->where($criteria, $value); + self::assertInstanceOf(WhereQuery::class, $query); + + $item = $query->getQuery()->first(); + $criteria = str_replace("CUSTOM ", "", $criteria); + $expected = $value === null ? [$criteria] : [$criteria, $value]; + if ($date === true && $value instanceof Carbon) { + $date_format = ClientManager::get('date_format', 'd M y'); + $expected[1] = $value->format($date_format); + } + + self::assertIsArray($item); + self::assertIsString($item[0]); + if($value !== null) { + self::assertCount(2, $item); + self::assertIsString($item[1]); + }else{ + self::assertCount(1, $item); + } + self::assertSame($expected, $item); + } + + /** + * Assert header search criteria + * @param Folder $folder + * @param string $criteria + * @param mixed|null $value + * + * @return void + * @throws AuthFailedException + * @throws ConnectionFailedException + * @throws ImapBadRequestException + * @throws ImapServerErrorException + * @throws InvalidWhereQueryCriteriaException + * @throws ResponseException + * @throws RuntimeException + */ + protected function assertHeaderSearchCriteria(Folder $folder, string $criteria, mixed $value = null): void { + $query = $folder->query()->whereHeader($criteria, $value); + self::assertInstanceOf(WhereQuery::class, $query); + + $item = $query->getQuery()->first(); + + self::assertIsArray($item); + self::assertIsString($item[0]); + self::assertCount(1, $item); + self::assertSame(['HEADER '.$criteria.' '.$value], $item); + } +} \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/1366671050@github.com.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/1366671050@github.com.eml new file mode 100644 index 000000000..97cb7ad1a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/1366671050@github.com.eml @@ -0,0 +1,108 @@ +Return-Path: +Delivered-To: someone@domain.tld +Received: from mx.domain.tld + by localhost with LMTP + id SABVMNfGqWP+PAAA0J78UA + (envelope-from ) + for ; Mon, 26 Dec 2022 17:07:51 +0100 +Received: from localhost (localhost [127.0.0.1]) + by mx.domain.tld (Postfix) with ESMTP id C3828140227 + for ; Mon, 26 Dec 2022 17:07:51 +0100 (CET) +X-Virus-Scanned: Debian amavisd-new at mx.domain.tld +X-Spam-Flag: NO +X-Spam-Score: -4.299 +X-Spam-Level: +X-Spam-Status: No, score=-4.299 required=6.31 tests=[BAYES_00=-1.9, + DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, + DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_IMAGE_ONLY_16=1.092, + HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_MED=-2.3, + RCVD_IN_MSPIKE_H2=-0.001, T_KAM_HTML_FONT_INVALID=0.01] + autolearn=ham autolearn_force=no +Received: from mx.domain.tld ([127.0.0.1]) + by localhost (mx.domain.tld [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id JcIS9RuNBTNx for ; + Mon, 26 Dec 2022 17:07:21 +0100 (CET) +Received: from smtp.github.com (out-26.smtp.github.com [192.30.252.209]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mx.domain.tld (Postfix) with ESMTPS id 6410B13FEB2 + for ; Mon, 26 Dec 2022 17:07:21 +0100 (CET) +Received: from github-lowworker-891b8d2.va3-iad.github.net (github-lowworker-891b8d2.va3-iad.github.net [10.48.109.104]) + by smtp.github.com (Postfix) with ESMTP id 176985E0200 + for ; Mon, 26 Dec 2022 08:07:14 -0800 (PST) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; + s=pf2014; t=1672070834; + bh=v91TPiLpM/cpUb4lgt2NMIUfM4HOIxCEWMR1+JTco+Q=; + h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: + List-Archive:List-Post:List-Unsubscribe:From; + b=jW4Tac9IjWAPbEImyiYf1bzGLzY3ceohVbBg1V8BlpMTQ+o+yY3YB0eOe20hAsqZR + jrDjArx7rKQcslqBFL/b2B1C51rHuCBrz2cccLEERu9l/u0mTGCxTNtCRXHbCKbnR1 + VLWBeFLjATHth83kK6Kt7lkVuty+G3V1B6ZKPhCI= +Date: Mon, 26 Dec 2022 08:07:14 -0800 +From: Username +Reply-To: Webklex/php-imap +To: Webklex/php-imap +Cc: Subscribed +Message-ID: +In-Reply-To: +References: +Subject: Re: [Webklex/php-imap] Read all folders? (Issue #349) +Mime-Version: 1.0 +Content-Type: multipart/alternative; + boundary="--==_mimepart_63a9c6b293fe_65b5c71014155a"; + charset=UTF-8 +Content-Transfer-Encoding: 7bit +Precedence: list +X-GitHub-Sender: consigliere23 +X-GitHub-Recipient: Webklex +X-GitHub-Reason: subscribed +List-ID: Webklex/php-imap +List-Archive: https://github.com/Webklex/php-imap +List-Post: +List-Unsubscribe: , + +X-Auto-Response-Suppress: All +X-GitHub-Recipient-Address: someone@domain.tld + + +----==_mimepart_63a9c6b293fe_65b5c71014155a +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Any updates? + +-- +Reply to this email directly or view it on GitHub: +https://github.com/Webklex/php-imap/issues/349#issuecomment-1365266070 +You are receiving this because you are subscribed to this thread. + +Message ID: +----==_mimepart_63a9c6b293fe_65b5c71014155a +Content-Type: text/html; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + +

+

Any updates?

+ +


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <Webklex/php-imap/issues/349/1365266070@github.com>

+ +----==_mimepart_63a9c6b293fe_65b5c71014155a-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_encoded_filename.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_encoded_filename.eml new file mode 100644 index 000000000..231d04520 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_encoded_filename.eml @@ -0,0 +1,10 @@ +Content-Type: multipart/mixed; + boundary="BOUNDARY" + +--BOUNDARY +Content-Type: application/vnd.ms-excel; name="=?UTF-8?Q?Prost=C5=99eno=5F2014=5Fposledn=C3=AD_voln=C3=A9_term=C3=ADny.xls?="; charset="UTF-8" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="=?UTF-8?Q?Prost=C5=99eno=5F2014=5Fposledn=C3=AD_voln=C3=A9_term=C3=ADny.xls?=" + +0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAACAAAAwgAAAAAA +AAAAEAAA/v///wAAAAD+////AAAAAMAAAADBAAAA//////////////////////////////// diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_long_filename.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_long_filename.eml new file mode 100644 index 000000000..8630280fe --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_long_filename.eml @@ -0,0 +1,55 @@ +Content-Type: multipart/mixed; + boundary="BOUNDARY" + +--BOUNDARY +Content-Type: text/plain; + name*0*=utf-8''Buchungsbest%C3%A4tigung-%20Rechnung-Gesch%C3%A4ftsbedingung; + name*1*=en-Nr.B123-45%20-%20XXXX%20xxxxxxxxxxxxxxxxx%20XxxX%2C%20L%C3%BCd; + name*2*=xxxxxxxx%20-%20VM%20Klaus%20XXXXXX%20-%20xxxxxxxx.pdf +Content-Disposition: attachment; + filename*0*=utf-8''Buchungsbest%C3%A4tigung-%20Rechnung-Gesch%C3%A4ftsbedin; + filename*1*=gungen-Nr.B123-45%20-%20XXXXX%20xxxxxxxxxxxxxxxxx%20XxxX%2C; + filename*2*=%20L%C3%BCxxxxxxxxxx%20-%20VM%20Klaus%20XXXXXX%20-%20xxxxxxxx.p; + filename*3*=df +Content-Transfer-Encoding: base64 + +SGkh +--BOUNDARY +Content-Type: text/plain; charset=UTF-8; + name="=?UTF-8?B?MDFfQeKCrMOgw6TEhdCx2YrYr0BaLTAxMjM0NTY3ODktcXdlcnR5dWlv?= + =?UTF-8?Q?pasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzx?= + =?UTF-8?Q?cvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstu?= + =?UTF-8?Q?vz.txt?=" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename*0*=iso-8859-15''%30%31%5F%41%A4%E0%E4%3F%3F%3F%3F%40%5A%2D%30%31; + filename*1*=%32%33%34%35%36%37%38%39%2D%71%77%65%72%74%79%75%69%6F%70%61; + filename*2*=%73%64%66%67%68%6A%6B%6C%7A%78%63%76%62%6E%6D%6F%70%71%72%73; + filename*3*=%74%75%76%7A%2D%30%31%32%33%34%35%36%37%38%39%2D%71%77%65%72; + filename*4*=%74%79%75%69%6F%70%61%73%64%66%67%68%6A%6B%6C%7A%78%63%76%62; + filename*5*=%6E%6D%6F%70%71%72%73%74%75%76%7A%2D%30%31%32%33%34%35%36%37; + filename*6*=%38%39%2D%71%77%65%72%74%79%75%69%6F%70%61%73%64%66%67%68%6A; + filename*7*=%6B%6C%7A%78%63%76%62%6E%6D%6F%70%71%72%73%74%75%76%7A%2E%74; + filename*8*=%78%74 + +SGkh +--BOUNDARY +Content-Type: text/plain; charset=UTF-8; + name="=?UTF-8?B?MDJfQeKCrMOgw6TEhdCx2YrYr0BaLTAxMjM0NTY3ODktcXdlcnR5dWlv?= + =?UTF-8?Q?pasdfghjklzxcvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzx?= + =?UTF-8?Q?cvbnmopqrstuvz-0123456789-qwertyuiopasdfghjklzxcvbnmopqrstu?= + =?UTF-8?Q?vz.txt?=" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename*0*=UTF-8''%30%32%5F%41%E2%82%AC%C3%A0%C3%A4%C4%85%D0%B1%D9%8A%D8; + filename*1*=%AF%40%5A%2D%30%31%32%33%34%35%36%37%38%39%2D%71%77%65%72%74; + filename*2*=%79%75%69%6F%70%61%73%64%66%67%68%6A%6B%6C%7A%78%63%76%62%6E; + filename*3*=%6D%6F%70%71%72%73%74%75%76%7A%2D%30%31%32%33%34%35%36%37%38; + filename*4*=%39%2D%71%77%65%72%74%79%75%69%6F%70%61%73%64%66%67%68%6A%6B; + filename*5*=%6C%7A%78%63%76%62%6E%6D%6F%70%71%72%73%74%75%76%7A%2D%30%31; + filename*6*=%32%33%34%35%36%37%38%39%2D%71%77%65%72%74%79%75%69%6F%70%61; + filename*7*=%73%64%66%67%68%6A%6B%6C%7A%78%63%76%62%6E%6D%6F%70%71%72%73; + filename*8*=%74%75%76%7A%2E%74%78%74 + +SGkh +--BOUNDARY-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_no_disposition.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_no_disposition.eml new file mode 100644 index 000000000..ce0ea3e94 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/attachment_no_disposition.eml @@ -0,0 +1,9 @@ +Content-Type: multipart/mixed; + boundary="BOUNDARY" + +--BOUNDARY +Content-Type: application/vnd.ms-excel; name="=?UTF-8?Q?Prost=C5=99eno=5F2014=5Fposledn=C3=AD_voln=C3=A9_term=C3=ADny.xls?="; charset="UTF-8" +Content-Transfer-Encoding: base64 + +0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAACAAAAwgAAAAAA +AAAAEAAA/v///wAAAAD+////AAAAAMAAAADBAAAA//////////////////////////////// diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/bcc.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/bcc.eml new file mode 100644 index 000000000..1a6f16a85 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/bcc.eml @@ -0,0 +1,12 @@ +Return-Path: +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +From: from@there.com +To: to@here.com +Bcc: =?UTF-8?B?QV/igqxAe8OoX1o=?= +Reply-To: reply-to@here.com +Sender: sender@here.com + +Hi! diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/boolean_decoded_content.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/boolean_decoded_content.eml new file mode 100644 index 000000000..918180387 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/boolean_decoded_content.eml @@ -0,0 +1,31 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: multipart/mixed; boundary="=-vyqYb0SSRwuGFKv/Trdf" + +--=-vyqYb0SSRwuGFKv/Trdf +Content-Type: multipart/alternative; boundary="=-ewUvwipK68Y6itClYNpy" + +--=-ewUvwipK68Y6itClYNpy +Content-Type: text/plain; charset="us-ascii" + +Here is the problem mail + +Body text +--=-ewUvwipK68Y6itClYNpy +Content-Type: text/html; charset="us-ascii" + +Here is the problem mail + +Body text +--=-ewUvwipK68Y6itClYNpy-- + +--=-vyqYb0SSRwuGFKv/Trdf +Content-Type: application/pdf; name="Example Domain.pdf" +Content-Disposition: attachment; filename="Example Domain.pdf" +Content-Transfer-Encoding: base64 + +nnDusSNdG92w6Fuw61fMjAxOF8wMy0xMzMyNTMzMTkzLnBkZg==?= + +--=-vyqYb0SSRwuGFKv/Trdf-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/date-template.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/date-template.eml new file mode 100644 index 000000000..9354fd104 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/date-template.eml @@ -0,0 +1,8 @@ +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: %date_raw_header% +From: from@there.com +To: to@here.com + +Hi! diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/email_address.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/email_address.eml new file mode 100644 index 000000000..62b76d70f --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/email_address.eml @@ -0,0 +1,9 @@ +Message-ID: <123@example.com> +From: no_host +Cc: "This one: is \"right\"" , No-address +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi +How are you? diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email.eml new file mode 100644 index 000000000..293bc28ec --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email.eml @@ -0,0 +1,63 @@ +Return-Path: demo@cerstor.cz +Received: from webmail.my-office.cz (localhost [127.0.0.1]) + by keira.cofis.cz + ; Fri, 29 Jan 2016 14:25:40 +0100 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_5d4b2de51e6aad0435b4bfbd7a23594a" +Date: Fri, 29 Jan 2016 14:25:40 +0100 +From: demo@cerstor.cz +To: demo@cerstor.cz +Subject: embedded message +Message-ID: <7e5798da5747415e5b82fdce042ab2a6@cerstor.cz> +X-Sender: demo@cerstor.cz +User-Agent: Roundcube Webmail/1.0.0 + +--=_5d4b2de51e6aad0435b4bfbd7a23594a +Content-Transfer-Encoding: 7bit +Content-Type: text/plain; charset=US-ASCII; + format=flowed + +email that contains embedded message +--=_5d4b2de51e6aad0435b4bfbd7a23594a +Content-Transfer-Encoding: 8bit +Content-Type: message/rfc822; + name=demo.eml +Content-Disposition: attachment; + filename=demo.eml; + size=889 + +Return-Path: demo@cerstor.cz +Received: from webmail.my-office.cz (localhost [127.0.0.1]) + by keira.cofis.cz + ; Fri, 29 Jan 2016 14:22:13 +0100 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_995890bdbf8bd158f2cbae0e8d966000" +Date: Fri, 29 Jan 2016 14:22:13 +0100 +From: demo-from@cerstor.cz +To: demo-to@cerstor.cz +Subject: demo +Message-ID: <4cbaf57cb00891c53b32e1d63367740c@cerstor.cz> +X-Sender: demo@cerstor.cz +User-Agent: Roundcube Webmail/1.0.0 + +--=_995890bdbf8bd158f2cbae0e8d966000 +Content-Transfer-Encoding: 7bit +Content-Type: text/plain; charset=US-ASCII; + format=flowed + +demo text +--=_995890bdbf8bd158f2cbae0e8d966000 +Content-Transfer-Encoding: base64 +Content-Type: text/plain; + name=testfile.txt +Content-Disposition: attachment; + filename=testfile.txt; + size=29 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= +--=_995890bdbf8bd158f2cbae0e8d966000-- + + +--=_5d4b2de51e6aad0435b4bfbd7a23594a-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition-embedded.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition-embedded.eml new file mode 100644 index 000000000..df5fa40b9 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition-embedded.eml @@ -0,0 +1,61 @@ +Received: from webmail.my-office.cz (localhost [127.0.0.1]) + by keira.cofis.cz + ; Fri, 29 Jan 2016 14:25:40 +0100 +From: demo@cerstor.cz +To: demo@cerstor.cz +Date: Fri, 5 Apr 2019 12:10:49 +0200 +Subject: embedded_message_subject +Message-ID: +Accept-Language: pl-PL, nl-NL +Content-Language: pl-PL +Content-Type: multipart/mixed; + boundary="_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_" +MIME-Version: 1.0 + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: multipart/alternative; + boundary="_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_" + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: text/plain; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + +some txt + + + + + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: text/html; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + + +

some txt

+ + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_-- + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="file1.xlsx" +Content-Description: file1.xlsx +Content-Disposition: attachment; filename="file1.xlsx"; size=29; + creation-date="Fri, 05 Apr 2019 10:06:01 GMT"; + modification-date="Fri, 05 Apr 2019 10:10:49 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="file2.xlsx" +Content-Description: file2 +Content-Disposition: attachment; filename="file2.xlsx"; size=29; + creation-date="Fri, 05 Apr 2019 10:10:19 GMT"; + modification-date="Wed, 03 Apr 2019 11:04:32 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition.eml new file mode 100644 index 000000000..c5c8cffeb --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/embedded_email_without_content_disposition.eml @@ -0,0 +1,141 @@ +Return-Path: demo@cerstor.cz +Received: from webmail.my-office.cz (localhost [127.0.0.1]) + by keira.cofis.cz + ; Fri, 29 Jan 2016 14:25:40 +0100 +From: demo@cerstor.cz +To: demo@cerstor.cz +Date: Fri, 5 Apr 2019 13:48:50 +0200 +Subject: Subject +Message-ID: +Accept-Language: pl-PL, nl-NL +Content-Type: multipart/mixed; + boundary="_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_" +MIME-Version: 1.0 + +--_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: multipart/related; + boundary="_007_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_"; + type="multipart/alternative" + +--_007_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: multipart/alternative; + boundary="_000_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_" + +--_000_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: text/plain; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + +TexT + +[cid:file.jpg] + +--_000_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: text/html; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + +

TexT

= + +--_000_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_-- + +--_007_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: image/jpeg; name= + "file.jpg" +Content-Description: file.jpg +Content-Disposition: inline; filename= + "file.jpg"; + size=54558; creation-date="Fri, 05 Apr 2019 11:48:58 GMT"; + modification-date="Fri, 05 Apr 2019 11:48:58 GMT" +Content-ID: +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg== + +--_007_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_-- + +--_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: message/rfc822 + +Received: from webmail.my-office.cz (localhost [127.0.0.1]) + by keira.cofis.cz + ; Fri, 29 Jan 2016 14:25:40 +0100 +From: demo@cerstor.cz +To: demo@cerstor.cz +Date: Fri, 5 Apr 2019 12:10:49 +0200 +Subject: embedded_message_subject +Message-ID: +Accept-Language: pl-PL, nl-NL +Content-Language: pl-PL +Content-Type: multipart/mixed; + boundary="_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_" +MIME-Version: 1.0 + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: multipart/alternative; + boundary="_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_" + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: text/plain; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + +some txt + + + + + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: text/html; charset="iso-8859-2" +Content-Transfer-Encoding: quoted-printable + + +

some txt

+ + +--_000_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_-- + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="file1.xlsx" +Content-Description: file1.xlsx +Content-Disposition: attachment; filename="file1.xlsx"; size=29; + creation-date="Fri, 05 Apr 2019 10:06:01 GMT"; + modification-date="Fri, 05 Apr 2019 10:10:49 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_ +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="file2.xlsx" +Content-Description: file2 +Content-Disposition: attachment; filename="file2.xlsx"; size=29; + creation-date="Fri, 05 Apr 2019 10:10:19 GMT"; + modification-date="Wed, 03 Apr 2019 11:04:32 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_005_AC39946EBF5C034B87BABD5343E96979012671D40E38VM002emonsn_-- + +--_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="file3.xlsx" +Content-Description: file3.xlsx +Content-Disposition: attachment; filename="file3.xlsx"; + size=90672; creation-date="Fri, 05 Apr 2019 11:46:30 GMT"; + modification-date="Thu, 28 Mar 2019 08:07:58 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_ +Content-Type: application/x-zip-compressed; name="file4.zip" +Content-Description: file4.zip +Content-Disposition: attachment; filename="file4.zip"; size=29; + creation-date="Fri, 05 Apr 2019 11:48:45 GMT"; + modification-date="Fri, 05 Apr 2019 11:35:24 GMT" +Content-Transfer-Encoding: base64 + +IHRoaXMgaXMgY29udGVudCBvZiB0ZXN0IGZpbGU= + +--_008_AC39946EBF5C034B87BABD5343E96979012671D9F7E4VM002emonsn_-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_attachment.eml new file mode 100644 index 000000000..3e929a349 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_attachment.eml @@ -0,0 +1,56 @@ +Return-Path: +Delivered-To: +Received: from mx.domain.tld + by localhost (Dovecot) with LMTP id T7mwLn3ddlvKWwAA0J78UA + for ; Fri, 17 Aug 2018 16:36:45 +0200 +Received: from localhost (localhost [127.0.0.1]) + by mx.domain.tld (Postfix) with ESMTP id B642913BA0BE2 + for ; Fri, 17 Aug 2018 16:36:45 +0200 (CEST) +X-Virus-Scanned: Debian amavisd-new at mx.domain.tld +X-Spam-Flag: NO +X-Spam-Score: 1.103 +X-Spam-Level: * +X-Spam-Status: No, score=1.103 required=6.31 tests=[ALL_TRUSTED=-1, + OBFU_TEXT_ATTACH=1, TRACKER_ID=1.102, TVD_SPACE_RATIO=0.001] + autolearn=no autolearn_force=no +Received: from mx.domain.tld ([127.0.0.1]) + by localhost (mx.domain.tld [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id L8E9vyX80d44 for ; + Fri, 17 Aug 2018 16:36:39 +0200 (CEST) +Received: from [127.0.0.1] (ip.dynamic.domain.tld [192.168.0.24]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by mx.domain.tld (Postfix) with ESMTPSA id EF01E13BA0BD7 + for ; Fri, 17 Aug 2018 16:36:38 +0200 (CEST) +Sender: testsender +Message-ID: +Date: Fri, 17 Aug 2018 14:36:24 +0000 +Subject: ogqMVHhz7swLaq2PfSWsZj0k99w8wtMbrb4RuHdNg53i76B7icIIM0zIWpwGFtnk +From: testfrom +Reply-To: testreply_to +To: testnameto +Cc: testnamecc +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="_=_swift_v4_1534516584_32c032a3715d2dfd5cd84c26f84dba8d_=_" +X-Priority: 1 (Highest) + + + + +--_=_swift_v4_1534516584_32c032a3715d2dfd5cd84c26f84dba8d_=_ +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: quoted-printable + +n1IaXFkbeqKyg4lYToaJ3u1Ond2EDrN3UWuiLFNjOLJEAabSYagYQaOHtV5QDlZE + +--_=_swift_v4_1534516584_32c032a3715d2dfd5cd84c26f84dba8d_=_ +Content-Type: application/octet-stream; name=6mfFxiU5Yhv9WYJx.txt +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename=6mfFxiU5Yhv9WYJx.txt + +em5rNTUxTVAzVFAzV1BwOUtsMWduTEVycldFZ2tKRkF0dmFLcWtUZ3JrM2RLSThkWDM4WVQ4QmFW +eFJjT0VSTg== + +--_=_swift_v4_1534516584_32c032a3715d2dfd5cd84c26f84dba8d_=_-- + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_bounce.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_bounce.eml new file mode 100644 index 000000000..a1f5683f0 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/example_bounce.eml @@ -0,0 +1,96 @@ +Return-Path: <> +Received: from somewhere.your-server.de + by somewhere.your-server.de with LMTP + id 3TP8LrElAGSOaAAAmBr1xw + (envelope-from <>); Thu, 02 Mar 2023 05:27:29 +0100 +Envelope-to: demo@foo.de +Delivery-date: Thu, 02 Mar 2023 05:27:29 +0100 +Authentication-Results: somewhere.your-server.de; + iprev=pass (somewhere06.your-server.de) smtp.remote-ip=1b21:2f8:e0a:50e4::2; + spf=none smtp.mailfrom=<>; + dmarc=skipped +Received: from somewhere06.your-server.de ([1b21:2f8:e0a:50e4::2]) + by somewhere.your-server.de with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 + (Exim 4.94.2) + id 1pXaXR-0006xQ-BN + for demo@foo.de; Thu, 02 Mar 2023 05:27:29 +0100 +Received: from [192.168.0.10] (helo=sslproxy01.your-server.de) + by somewhere06.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) + (Exim 4.92) + id 1pXaXO-000LYP-9R + for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100 +Received: from localhost ([127.0.0.1] helo=sslproxy01.your-server.de) + by sslproxy01.your-server.de with esmtps (TLSv1.3:TLS_AES_256_GCM_SHA384:256) + (Exim 4.92) + id 1pXaXO-0008gy-7x + for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100 +Received: from Debian-exim by sslproxy01.your-server.de with local (Exim 4.92) + id 1pXaXO-0008gb-6g + for demo@foo.de; Thu, 02 Mar 2023 05:27:26 +0100 +X-Failed-Recipients: ding@ding.de +Auto-Submitted: auto-replied +From: Mail Delivery System +To: demo@foo.de +Content-Type: multipart/report; report-type=delivery-status; boundary=1677731246-eximdsn-678287796 +MIME-Version: 1.0 +Subject: Mail delivery failed +Message-Id: +Date: Thu, 02 Mar 2023 05:27:26 +0100 +X-Virus-Scanned: Clear (ClamAV 0.103.8/26827/Wed Mar 1 09:28:49 2023) +X-Spam-Score: 0.0 (/) +Delivered-To: bar-demo@foo.de + +--1677731246-eximdsn-678287796 +Content-type: text/plain; charset=us-ascii + +This message was created automatically by mail delivery software. + +A message sent by + + + +could not be delivered to one or more of its recipients. The following +address(es) failed: + + ding@ding.de + host 36.143.65.153 [36.143.65.153] + SMTP error from remote mail server after pipelined end of data: + 550-Verification failed for + 550-Unrouteable address + 550 Sender verify failed + +--1677731246-eximdsn-678287796 +Content-type: message/delivery-status + +Reporting-MTA: dns; sslproxy01.your-server.de + +Action: failed +Final-Recipient: rfc822;ding@ding.de +Status: 5.0.0 +Remote-MTA: dns; 36.143.65.153 +Diagnostic-Code: smtp; 550-Verification failed for + 550-Unrouteable address + 550 Sender verify failed + +--1677731246-eximdsn-678287796 +Content-type: message/rfc822 + +Return-path: +Received: from [31.18.107.47] (helo=127.0.0.1) + by sslproxy01.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) + (Exim 4.92) + (envelope-from ) + id 1pXaXO-0008eK-11 + for ding@ding.de; Thu, 02 Mar 2023 05:27:26 +0100 +Date: Thu, 2 Mar 2023 05:27:25 +0100 +To: ding +From: =?iso-8859-1?Q?S=C3=BCderbar_Foo_=28SI=29_GmbH?= +Subject: Test +Message-ID: +X-Mailer: PHPMailer 6.7.1 (https://github.com/PHPMailer/PHPMailer) +Return-Path: bounce@foo.de +MIME-Version: 1.0 +Content-Type: text/html; charset=iso-8859-1 +X-Authenticated-Sender: demo@foo.de + +
Hallo, dies ist ein Beispiel-Text.
\ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/four_nested_emails.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/four_nested_emails.eml new file mode 100644 index 000000000..0b34e9866 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/four_nested_emails.eml @@ -0,0 +1,69 @@ +To: test@example.com +From: test@example.com +Subject: 3-third-subject +Content-Type: multipart/mixed; + boundary="------------2E5D78A17C812FEFF825F7D5" + +This is a multi-part message in MIME format. +--------------2E5D78A17C812FEFF825F7D5 +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +3-third-content +--------------2E5D78A17C812FEFF825F7D5 +Content-Type: message/rfc822; + name="2-second-email.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="2-second-email.eml" + +To: test@example.com +From: test@example.com +Subject: 2-second-subject +Content-Type: multipart/mixed; + boundary="------------9919377E37A03209B057D47F" + +This is a multi-part message in MIME format. +--------------9919377E37A03209B057D47F +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +2-second-content +--------------9919377E37A03209B057D47F +Content-Type: message/rfc822; + name="1-first-email.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="1-first-email.eml" + +To: test@example.com +From: test@example.com +Subject: 1-first-subject +Content-Type: multipart/mixed; + boundary="------------0919377E37A03209B057D47A" + +This is a multi-part message in MIME format. +--------------0919377E37A03209B057D47A +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +1-first-content +--------------0919377E37A03209B057D47A +Content-Type: message/rfc822; + name="0-zero-email.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="0-zero-email.eml" + +To: test@example.com +From: test@example.com +Subject: 0-zero-subject +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +0-zero-content +--------------0919377E37A03209B057D47A-- + +--------------9919377E37A03209B057D47F-- + +--------------2E5D78A17C812FEFF825F7D5-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/gbk_charset.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/gbk_charset.eml new file mode 100644 index 000000000..b40936bd4 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/gbk_charset.eml @@ -0,0 +1,9 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="X-GBK" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/html_only.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/html_only.eml new file mode 100644 index 000000000..ce3ee17cb --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/html_only.eml @@ -0,0 +1,9 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/html; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/imap_mime_header_decode_returns_false.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/imap_mime_header_decode_returns_false.eml new file mode 100644 index 000000000..af3a7f363 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/imap_mime_header_decode_returns_false.eml @@ -0,0 +1,9 @@ +From: from@there.com +To: to@here.com +Subject: =?UTF-8?B?nnDusSNdG92w6Fuw61fMjAxOF8wMy0xMzMyNTMzMTkzLnBkZg==?= +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/inline_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/inline_attachment.eml new file mode 100644 index 000000000..be60f5983 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/inline_attachment.eml @@ -0,0 +1,41 @@ +Content-Type: multipart/mixed; + boundary="----=_Part_1114403_1160068121.1505882828080" + +------=_Part_1114403_1160068121.1505882828080 +Content-Type: multipart/related; + boundary="----=_Part_1114404_576719783.1505882828080" + +------=_Part_1114404_576719783.1505882828080 +Content-Type: text/html;charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + +------=_Part_1114404_576719783.1505882828080 +Content-Type: image/png +Content-Disposition: inline +Content-Transfer-Encoding: base64 +Content-ID: + +iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAB+FBMVEUAAAA/mUPidDHiLi5Cn0Xk +NTPmeUrkdUg/m0Q0pEfcpSbwaVdKskg+lUP4zA/iLi3msSHkOjVAmETdJSjtYFE/lkPnRj3sWUs8 +kkLeqCVIq0fxvhXqUkbVmSjwa1n1yBLepyX1xxP0xRXqUkboST9KukpHpUbuvRrzrhF/ljbwalju +ZFM4jELaoSdLtElJrUj1xxP6zwzfqSU4i0HYnydMtUlIqUfywxb60AxZqEXaoifgMCXptR9MtklH +pEY2iUHWnSjvvRr70QujkC+pUC/90glMuEnlOjVMt0j70QriLS1LtEnnRj3qUUXfIidOjsxAhcZF +o0bjNDH0xxNLr0dIrUdmntVTkMoyfL8jcLBRuErhJyrgKyb4zA/5zg3tYFBBmUTmQTnhMinruBzv +vhnxwxZ/st+Ktt5zp9hqota2vtK6y9FemNBblc9HiMiTtMbFtsM6gcPV2r6dwroseLrMrbQrdLGd +yKoobKbo3Zh+ynrgVllZulTsXE3rV0pIqUf42UVUo0JyjEHoS0HmsiHRGR/lmRz/1hjqnxjvpRWf +wtOhusaz0LRGf7FEfbDVmqHXlJeW0pbXq5bec3fX0nTnzmuJuWvhoFFhm0FtrziBsjaAaDCYWC+u +Si6jQS3FsSfLJiTirCOkuCG1KiG+wSC+GBvgyhTszQ64Z77KAAAARXRSTlMAIQRDLyUgCwsE6ebm +5ubg2dLR0byXl4FDQzU1NDEuLSUgC+vr6urq6ubb29vb2tra2tG8vLu7u7uXl5eXgYGBgYGBLiUA +LabIAAABsElEQVQoz12S9VPjQBxHt8VaOA6HE+AOzv1wd7pJk5I2adpCC7RUcHd3d3fXf5PvLkxh +eD++z+yb7GSRlwD/+Hj/APQCZWxM5M+goF+RMbHK594v+tPoiN1uHxkt+xzt9+R9wnRTZZQpXQ0T +5uP1IQxToyOAZiQu5HEpjeA4SWIoksRxNiGC1tRZJ4LNxgHgnU5nJZBDvuDdl8lzQRBsQ+s9PZt7 +s7Pz8wsL39/DkIfZ4xlB2Gqsq62ta9oxVlVrNZpihFRpGO9fzQw1ms0NDWZz07iGkJmIFH8xxkc3 +a/WWlubmFkv9AB2SEpDvKxbjidN2faseaNV3zoHXvv7wMODJdkOHAegweAfFPx4G67KluxzottCU +9n8CUqXzcIQdXOytAHqXxomvykhEKN9EFutG22p//0rbNvHVxiJywa8yS2KDfV1dfbu31H8jF1RH +iTKtWYeHxUvq3bn0pyjCRaiRU6aDO+gb3aEfEeVNsDgm8zzLy9egPa7Qt8TSJdwhjplk06HH43ZN +J3s91KKCHQ5x4sw1fRGYDZ0n1L4FKb9/BP5JLYxToheoFCVxz57PPS8UhhEpLBVeAAAAAElFTkSu +QmCC +------=_Part_1114404_576719783.1505882828080-- + +------=_Part_1114403_1160068121.1505882828080-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275-2.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275-2.eml new file mode 100644 index 000000000..d80e66ed4 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275-2.eml @@ -0,0 +1,123 @@ +Received: from AS4PR02MB8234.eurprd02.prod.outlook.com (2603:10a6:20b:4f1::17) + by PA4PR02MB7071.eurprd02.prod.outlook.com with HTTPS; Wed, 18 Jan 2023 + 09:17:10 +0000 +Received: from AS1PR02MB7917.eurprd02.prod.outlook.com (2603:10a6:20b:4a5::5) + by AS4PR02MB8234.eurprd02.prod.outlook.com (2603:10a6:20b:4f1::17) with + Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.19; Wed, 18 Jan + 2023 09:17:09 +0000 +Received: from AS1PR02MB7917.eurprd02.prod.outlook.com + ([fe80::4871:bdde:a499:c0d9]) by AS1PR02MB7917.eurprd02.prod.outlook.com + ([fe80::4871:bdde:a499:c0d9%9]) with mapi id 15.20.5986.023; Wed, 18 Jan 2023 + 09:17:09 +0000 +From: =?iso-8859-1?Q?Martin_B=FClow_Larsen?= +To: Cofman Drift +Subject: Test 1017 +Thread-Topic: Test 1017 +Thread-Index: AdkrHaKsy+bUiL/eTIS5W3AP+zzLjQ== +Date: Wed, 18 Jan 2023 09:17:09 +0000 +Message-ID: + +Accept-Language: da-DK, en-US +Content-Language: en-US +X-MS-Exchange-Organization-AuthAs: Internal +X-MS-Exchange-Organization-AuthMechanism: 04 +X-MS-Exchange-Organization-AuthSource: AS1PR02MB7917.eurprd02.prod.outlook.com +X-MS-Has-Attach: +X-MS-Exchange-Organization-Network-Message-Id: + 98cea1c9-a497-454a-6606-08daf934c6c4 +X-MS-Exchange-Organization-SCL: -1 +X-MS-TNEF-Correlator: +X-MS-Exchange-Organization-RecordReviewCfmType: 0 +x-ms-publictraffictype: Email +X-Microsoft-Antispam-Mailbox-Delivery: + ucf:0;jmr:0;auth:0;dest:I;ENG:(910001)(944506478)(944626604)(920097)(425001)(930097); +X-Microsoft-Antispam-Message-Info: + BzqL6hvPyQW0lSkWGop6vQlsIZK48umY74vuKlNgF0pb/H659W+0fuTB+6guqGM0oof00mlzu3gn1pu1R5pUOE2Fb58OqnBEFkB30vVrG6TNsG/6KBtecXkP3FptqO/WRmsxCQx7bK7J2VyS2SbOibqX8mDZhkTrwP1+IA0R9eD0/NvoMqX9GssewUDxSAbaaKdADCuU1dG7qpF8M9tfLDJz+dUL5qZoO+oGINGLLdo2y6Z/F+h3UWv7BXiS4BJKc+jwAng26BUMKmg2VVRdMvc+LbZTovUr9hyEq1orS9fOg1iIV6sPcyIVl3NIEy5bHMYh1d6sUCqvTO1UPSdf7lIvKxSszyKptIPNgioOvFpF9tTHDyKU5p1IiLm5FxW/+kGdPq6ZoTIZVriJoyjx6gWKpPY3vHN6bHUK9mA+LspIYAeuDFFvwkZx2b2Rtw3S99S7zz3eBqv3xlGqJixx/apl4Af7ZaxKFpMj9XZXAQVIv9BA0tIA+1nLByt4dPW4Xzoj3KcBbX5K/HkuR/30Lrq7gRQQDyNYgf5S/MO2MLJqcvnVFPXgVubK6XFu5quDibsZjPjxOUfBTJkJ/n4gB8Z8/TOM0oKD76hszXXoaWd9leUeQ1x88oy+QuXPRxzuLzVec3GiPNMYA42QvvTiWmrrhdceRzhV0J7pJBbi10ik+hXqSeNkldgktd5cWPss5F74yxAaEaPJO9I7MOUpE0XzlRfljPptykrIQt8SARMllykzJNrDt8VAl37ArEZbWxFLm3RuypOI0zgCZMRLf5JeElpCv1ay4wilz4vsYGr4fs3KUQzI1YY43uaDxNMz8k7dH/UkC9Dfg1oyHlNs+w== +Content-Type: multipart/alternative; + boundary="_000_AS1PR02MB791721260DE0273A15AFEC3EB5C79AS1PR02MB7917eurp_" +MIME-Version: 1.0 + +--_000_AS1PR02MB791721260DE0273A15AFEC3EB5C79AS1PR02MB7917eurp_ +Content-Type: text/plain; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +Test + +Med venlig hilsen +Martin Larsen +Feline Holidays A/S +Tlf 78 77 04 12 + + + +--_000_AS1PR02MB791721260DE0273A15AFEC3EB5C79AS1PR02MB7917eurp_ +Content-Type: text/html; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
+

Test

+

 

+

= +Med venlig hilsen

+

Martin Larsen

+

Feline Holidays A/S

+

Tlf 78 77 04 12

+

 

+

 

+
+ + + +--_000_AS1PR02MB791721260DE0273A15AFEC3EB5C79AS1PR02MB7917eurp_-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275.eml new file mode 100644 index 000000000..642d6a425 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-275.eml @@ -0,0 +1,208 @@ +Received: from FR0P281MB2649.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:50::12) + by BEZP281MB2374.DEUP281.PROD.OUTLOOK.COM with HTTPS; Tue, 17 Jan 2023 + 09:25:19 +0000 +Received: from DB6P191CA0002.EURP191.PROD.OUTLOOK.COM (2603:10a6:6:28::12) by + FR0P281MB2649.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:50::12) with Microsoft + SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id + 15.20.5986.23; Tue, 17 Jan 2023 09:25:18 +0000 +Received: from DB5EUR02FT011.eop-EUR02.prod.protection.outlook.com + (2603:10a6:6:28:cafe::3b) by DB6P191CA0002.outlook.office365.com + (2603:10a6:6:28::12) with Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.19 via Frontend + Transport; Tue, 17 Jan 2023 09:25:18 +0000 +Authentication-Results: spf=pass (sender IP is 80.241.56.171) + smtp.mailfrom=*****; dkim=pass (signature was verified) + header.d=jankoppe.de;dmarc=pass action=none + header.from=jankoppe.de;compauth=pass reason=100 +Received-SPF: Pass (protection.outlook.com: domain of **** designates + 80.241.56.171 as permitted sender) receiver=protection.outlook.com; + client-ip=80.241.56.171; helo=mout-p-201.mailbox.org; pr=C +Received: from **** + DB5EUR02FT011.mail.protection.outlook.com (10.13.58.70) with Microsoft SMTP + Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id + 15.20.6002.13 via Frontend Transport; Tue, 17 Jan 2023 09:25:18 +0000 +Received: from **** + (***) with Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.2375.34; Tue, 17 + Jan 2023 10:25:18 +0100 +Received: from ***** + (***) with Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.34; Tue, 17 Jan + 2023 10:25:16 +0100 +Received: from **** + (***) with Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.1.2375.34 via Frontend + Transport; Tue, 17 Jan 2023 10:25:16 +0100 +Received: from ***** + (***) with Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521) id 15.1.2375.34; Tue, 17 + Jan 2023 10:25:18 +0100 +IronPort-SDR: qF6UeVYj8pb73gXrskSNOtfmUEgr2JLTtqbIK+/6ymuIu+hw8DzzyKrOGqm7zNPwG/4zr+ma5y + XERFv6Zyf/cxrWoVjWXswWrkCVjqQuHglLaONZt1Mg4okFzEByeEZsyg3/3n6kI4O+kgViBgLW + nNMzGlNLSqYBX+EDhOfE1GEWB/4iRbwDY32SnTr5BYqR0HwgHf+0M0E3b23/NqV6iYrF3KETah + cLtLRt/b5JY6f5KvmKoz0Y395r7MwryWR1eLKAU2j3w+ioNYBUw36K/hsIRojcquvQk9w3Qtfu + Yz1BUNwOEOwfxr0VjQScHirO +X-IRON-External-Mail-Tag: Extern +X-IronPort-MID: 60840111 +X-IPAS-Result: =?us-ascii?q?A0G0CQCSaMZjmKs48VBaglqEBz5Fk0mfZoFqEw8BAQEBA?= + =?us-ascii?q?QEBAQEJRAQBAQQDihcCJToEDQECBAEBAQEDAgMBAQEBBQEBAQQBAQECAQEGA?= + =?us-ascii?q?wEBAQIQAQEBAQEBAQEVCRkFDhAFLw1XDV0LgUQLgXQLAzENgjgiggQsgXYnA?= + =?us-ascii?q?QE4hE6DIwetVIEBgggBAQaCY5xECYFBi12ESYEhHD8BgU2EP4VPhXKaXIE7f?= + =?us-ascii?q?IEnDoFIgSk3A0QdQAMLbQpANRZKKxobB4EJKigVAwQEAwIGEwMiAg0oMRQEK?= + =?us-ascii?q?RMNJyZpCQIDImYDAwQoLQkgHwcmJDwHVj0CDx83BgMJAwIhToEgJAUDCxUqR?= + =?us-ascii?q?wQINgUGUhICCA8SDyxDDkI3NBMGgQYLDhEDUIFOBIENfwpXxUKgLYIqgVChG?= + =?us-ascii?q?oNmAZMikiGXS6gMgXwKFoFcTSQUgyJPAQIBAQENAQIBAQMBAgEBAQkBAQEBj?= + =?us-ascii?q?jaEDIosQzE7AgcLAQEDCYwjAQE?= +IronPort-PHdr: A9a23:3aIm3RBfYL78XRTcz0LxUyQUT0MY04WdBeb1wqQuh78GSKm/5ZOqZ + BWZua8wygaRAM6CsKgMotGVmp6jcFRI2YyGvnEGfc4EfD4+ouJSoTYdBtWYA1bwNv/gYn9yN + s1DUFh44yPzahANS47xaFLIv3K98yMZFAnhOgppPOT1HZPZg9iq2+yo9JDffQVFiCCgbb9uL + Bi6ohjdu8cIjYB/Nqs/1xzFr2dHdOhR2W5mP0+YkQzm5se38p5j8iBQtOwk+sVdT6j0fLk2Q + KJBAjg+PG87+MPktR/YTQuS/XQcSXkZkgBJAwfe8h73WIr6vzbguep83CmaOtD2TawxVD+/4 + apnVAPkhSEaPDM/7WrZiNF/jLhDrRyiuhJxw5Dab52aOvRwcazQZs8aSGhbU8pNSyBNHp+wY + o0SBOQBJ+ZYqIz9qkMKoxSkAwmnGebhyjhQhn/uw6IxzuMsERnB3Aw7A9IDq3bUo8/zNKcRV + uC11LHIwivZY/xLxzjw8Y7FeQ0urv+QR7x/a9bRyVUxGAPfiFWdsZDpMjKV2OkTvWWV7+RtW + OOhhmMmqAx8oDuiy8Uih4fGh48Y1FPJ+Th4zYs6J9C0VFJ3bN64HZZftiyXKoR7Tt4kTmp1u + yg60qULtJ2ncCQQ1pgqyAPTZ+aHfoWJ+B7vSeScLSp+iXl4YrywnQyy/lKlyuDkVsm7zlJKr + i1dn9nJsXANygDT5tGfSvdk4EutxSuD2xrW6u5eIEA0kbHUK5kuw7IqkZoTq0vDEjf3mEXwk + qCWal0p9+u05+j9fLnrqYKQO5V0hwz/KKgih86yDfkgPggLRWeb+OC81LP5/U3+RbVHluU2k + q7CsJDGPskbpLS2AwlW0oYk8xa/Fymp3M4FknYZNF5FfgmIgJDzO17SOPD4Eeu/g1O0nTt23 + /zGJKHuAo3RLnjfl7fsZbJ960lTyAoyy9BT/olUCqwZIPLrXU/xrsDYAwQiPAyp2eboFc9y2 + poQWWKIGK+YPrndsUWV6e41PuaDetxdhDGoL/8q5virlmIhgVgHYYGjwIEbYTW2Ge55Kl+VJ + 3bh0fkbFmJfnAM4BM/tkEWPGWpLYG2ud6A14DI8EJqrS4vOENP+yIed1Tu2S8UFLltNDUqBR + C+ASg== +IronPort-Data: A9a23:VhC+4aKGZF33Q9F0FE+RvpMlxSXFcZb7ZxGr2PjKsXjdYENS1zBVm + zYfDDuGOvjcMGT0etAkYN6x8kwD7MLQm9Q3G1ForCE8RH9jl5HIVI+TRqvSF3rJd5WcFiqLz + Cm/hv3odp1coqr0/E/F3oAMLhCQ7InQLlbGILes1htZGEk1F0/NtTo5w7Ri2tcx3oDga++wk + YqaT/P3aQfNNwFcbzp8B5Kr8HuDa9yr5Vv0FnRnDRx6lAe2e0s9VfrzFonoR5fMebS4K8bhL + wr15ODjpz2Bp3/BPfv++lrzWhVirrc/pmFigFIOM0SpqkAqSiDfTs/XnRfTAKtao2zhojx/9 + DlCnZWXSl0jF72Qo9YUcCEfFTpSP4Rt/KCSdBBTseTLp6HHW37r3ukrFARsZdRe/+92BWtJ5 + bofMj9lghKr17rwmu7iDLQywJ18daEHP6tH0p1k5SneFuoOQ5nFQKLS/dIe0DpYasVmQ66OO + 5JAMGMHgBLoWwRwMVsFObICo/qFn1bzdyRihGDOnP9ii4TU5Fcojeaxb4O9lsaxbcFSkUee4 + 3nb53z+GA0yPsGFxTPA/HW2mebVkWX3Veov+KaQ8/l3nBiLgzZLUVsTXFq/q/6pzEmkVLqzN + nD45AIniqto/mW7EuLPVj6A53ifkhw1cN5PRrhSBB629oLY5AOQB24hRzFHacA7uMJeeQHGx + mNljPu0X2E06uT9pWa1r+zI9WroUcQABTVaDRLoWzfp9PHPjenfZDrlQ8xnEajdYjbdQGmpm + mHiQMQWo7wVgYYh2r+//Favvt5Bjp3OUxJw/kCNBjvj6wp4YISid8qv81ezARd8wGSxEQXpU + JsswZL2AAUy4XelyHzlrAIlQejB2hp9GGeA6WOD5rF4n9hXx1atfJpL/BZ1L1pzP8APdFfBO + RGM4lMAv88JYiL6Ncebhr5d7ex0ncAM8vy6DpjpgiZmO/CdiSfcrH02DaJu9zmyziDAbp3Ty + b/AKJvyUSlDYUiW5Dq7RuEZ3L4tgzsj3XvUX4yzwBGt0dKjiI29Ft843K+1Rrlhtsus+VyNm + /4Gbpfi40gBDIXWP3eGmaZNdgpiBSZgWvjLRzl/K7TrzvxOQj9xUpc8ANoJJuRYokiivryZo + S/lAxEGmAGXaL+uAVziV02PoYjHBf5XxU/X9wR1Vbpx83R8M4up8okFcJ47Iesu+OB5lKcmT + fADeMKYGvkJRjmeo2YRapz0rYpDchW3hFvQYHP+PWViJsBtF17T59vpXgrz7y1SXCC5gs1v8 + bSv2zTSTYcHWwk/Xt3db+iizg3tsHVEwLByUkLEL8N9YkLp9IQ2eSX9guVuepMOIBPAwSOC2 + kCaDE5A9+XKpoY09vjPhLyF9tn2SrAjQxcDQWSCtOS4LyjX+Gan0LRsaufQcGCPTn7w9YWje + f5Rk6P2PsoBzQRDvIdLGrp2yb4zuon0rLhAwwU6QHjGYgj5Cr5kJXXaj8BDurcXnO1cvhaqH + 1rKoIEDf7CAOcfvF05XIxAqN7zR2fYRkzjUzPI0PESjunAup+faDBwMMknekjFZIZt0LJghn + bUrtvkQul62hRcdO9qbijxZqjaXJXsaXqR56pwXXN3xhgwwxg0QaJDQEHWsspSIdskJKgxwe + mbSgaPDg75b1gzFaXVqTSrB2u9UhJIvvhFWzQZceA3Sx4eY36E6jE9L7DA6bgVJ1REbgeh9D + W46ZUR6KJKH8ypsmMUeDXunHBtMBUPF90H8o7fTeLY1k6V1uqfxwKHR9ApDEI31M46RQ9SDw + Iyl9Q== +IronPort-HdrOrdr: A9a23:8y8NqqHssZLZ5JoIpLqE88eALOsnbusQ8zAXPidKKSC9E/b4qy + nKpp4mPHDP+VUssR0b9uxoW5PwI080l6QZ3WB5B97LNzUO01HFEGgN1+Xf/wE= +X-IronPort-Anti-Spam-Filtered: true +X-IronPort-AV: E=Sophos;i="5.97,222,1669071600"; + d="scan'208";a="60840111" +X-Amp-Result: SKIPPED(no attachment in message) +Received: from mout-p-201.mailbox.org ([80.241.56.171]) + by maila.burda.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2023 10:25:16 +0100 +Received: from smtp1.mailbox.org (smtp1.mailbox.org [10.196.197.1]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) + (No client certificate requested) + by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4Nx3QJ6GdJz9sQp + for <***>; Tue, 17 Jan 2023 10:25:12 +0100 (CET) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=****; s=MBO0001; + t=1673947512; + h=from:from:reply-to:subject:subject:date:date:message-id:message-id: + to:to:cc:mime-version:mime-version:content-type:content-type: + content-transfer-encoding:content-transfer-encoding; + bh=OMh+Pfp7SvIiDJjyXg53DevMPfaJRBhjQUkokwQIgDY=; + b=m3nM2KPbJdO7D+Vq/fMLLCXpkeDgvLs/JRzGTzWO4OoQhSaXLp76/vkBGPCU7BSGxir2Fu + g6e9Ggnrf0l8vL7rpvTgttta64wImaP9wOmJ0fOjzHcg/PX7sYjlUjyVyfThqZ7M5qg6/P + E9wItt4lQoUeQRVc6EoUlUaL7S+2R4P2WsQ6HCjulmpC3fmZdPOTXph/a1YfGvSfSj0pjp + LauH2n6EURKFmtMv8MbDcvTVKcq7o1bLGnK/RAjkLmRAORt+eC08IEAb5stVE6T6UPZ14Q + GUqrK2HEm5THS9vlH/11LwxwmnAdqUm8nl+Ymo3n1UNF9r8wkh8BUndGQFOQqQ== +Message-ID: <****> +Subject: Testing 123 +From: **** +To: *** +Content-Type: text/plain +Content-Transfer-Encoding: 7bit +Date: Tue, 17 Jan 2023 10:25:11 +0100 +Return-Path: *** +X-OrganizationHeadersPreserved: *** +X-MS-Exchange-Organization-ExpirationStartTime: 17 Jan 2023 09:25:18.2389 + (UTC) +X-MS-Exchange-Organization-ExpirationStartTimeReason: OriginalSubmit +X-MS-Exchange-Organization-ExpirationInterval: 1:00:00:00.0000000 +X-MS-Exchange-Organization-ExpirationIntervalReason: OriginalSubmit +X-MS-Exchange-Organization-Network-Message-Id: + ca3e116b-7c15-4efe-897e-08daf86cbfae +X-EOPAttributedMessage: 0 +X-MS-Exchange-Organization-MessageDirectionality: Originating +X-MS-Exchange-SkipListedInternetSender: + ip=[80.241.56.171];domain=mout-p-201.mailbox.org +X-MS-Exchange-ExternalOriginalInternetSender: + ip=[80.241.56.171];domain=mout-p-201.mailbox.org +X-CrossPremisesHeadersPromoted: + DB5EUR02FT011.eop-EUR02.prod.protection.outlook.com +X-CrossPremisesHeadersFiltered: + DB5EUR02FT011.eop-EUR02.prod.protection.outlook.com +X-MS-PublicTrafficType: Email +X-MS-TrafficTypeDiagnostic: DB5EUR02FT011:EE_|FR0P281MB2649:EE_ +X-MS-Exchange-Organization-AuthSource: **** +X-MS-Exchange-Organization-AuthAs: Anonymous +X-OriginatorOrg: *** +X-MS-Office365-Filtering-Correlation-Id: ca3e116b-7c15-4efe-897e-08daf86cbfae +X-MS-Exchange-Organization-SCL: 1 +X-Microsoft-Antispam: BCL:0; +X-Forefront-Antispam-Report: + CIP:193.26.100.144;CTRY:DE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mout-p-201.mailbox.org;PTR:mout-p-201.mailbox.org;CAT:NONE;SFS:(13230022)(4636009)(451199015)(6916009)(82310400005)(558084003)(2616005)(7116003)(6266002)(36005)(8676002)(86362001)(36756003)(5660300002)(1096003)(336012)(8936002)(156005)(7636003)(7596003);DIR:INB; +X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2023 09:25:18.1452 + (UTC) +X-MS-Exchange-CrossTenant-Network-Message-Id: ca3e116b-7c15-4efe-897e-08daf86cbfae +X-MS-Exchange-CrossTenant-Id: 0a3106bb-aab1-42df-9639-39f349ecd2a0 +X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0a3106bb-aab1-42df-9639-39f349ecd2a0**** +X-MS-Exchange-CrossTenant-AuthSource: *** +X-MS-Exchange-CrossTenant-AuthAs: Anonymous +X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem +X-MS-Exchange-Transport-CrossTenantHeadersStamped: FR0P281MB2649 +X-MS-Exchange-Transport-EndToEndLatency: 00:00:01.4839051 +X-MS-Exchange-Processed-By-BccFoldering: 15.20.6002.012 +X-Microsoft-Antispam-Mailbox-Delivery: + ucf:0;jmr:0;auth:0;dest:I;ENG:(910001)(944506478)(944626604)(920097)(930097); +X-Microsoft-Antispam-Message-Info: + =?iso-8859-1?Q?DN6oyY29jzFhRK1BGCOfg1yFnX4ACBaHBh9nbhnIoNZ4DGdi6zN+tIXnUR?= + =?iso-8859-1?Q?AY3F6SV1doOncexZBgqeE70YqvkB0xmo97NgnkQFb48xPvmZwoiAqkmIrS?= + =?iso-8859-1?Q?EbPesMMRL/pVX22Pde2C0KNThL0e02Li5ZCNvDxq+mEt0T9cww7HhoY6SS?= + =?iso-8859-1?Q?vMbDIBDA4c6Gyvb+34A6rYNFyHtZFVMas8S1KP4bV7QtI2WooRBzL1tOgM?= + =?iso-8859-1?Q?gyRVbzR69Mk++hTLhqTK7kBIkGMFhUC1McOMGMTOuUh9Ay7vMeY/oNGwOG?= + =?iso-8859-1?Q?WEFVsQjOz6lY4FIc3A+U5t3LMxkHtxRCql//ZhfKfjy78hPR7FCzYk70+T?= + =?iso-8859-1?Q?iCLlDZNF73KjvxH82FFKOersAl26L1kb2x5F/d1XJxAJe7BTG20/LXuMmx?= + =?iso-8859-1?Q?wGJs7s+C69LYa4cliwtGTMEuS6Rd7bOLihXnIy6hn8UhjVhNBv0+yGjint?= + =?iso-8859-1?Q?hbwBnQJ4Ny2jeS42bJYmKw+7Dnol+pphbvhjhtsDvKifo4Xx7xM45eV2s3?= + =?iso-8859-1?Q?wfKtSfeNGIR3Oi0VwreHTtsCOfvY8jbP+T2Z6KOFtQRvlUyutOFnOB2x1J?= + =?iso-8859-1?Q?BVgSblJzekltOB7gCAmZiCQnZuUMOtVVqRfURwUhOuQ47I/2LDJzi/NQnf?= + =?iso-8859-1?Q?XiqeHojof9SfngGas5TNx9tuQxmFqw4AWJE7iy4hxJo2ehSt4ReEvPzyt9?= + =?iso-8859-1?Q?1DTwLNYbyZ8Ub7Uq3EtUDE5vn3jY2thuVBo8eemdrjOvsx+hdH9RxcFwYz?= + =?iso-8859-1?Q?qU8NIflZ0TMRHTT2M2aBdzB9zsR3Kda+I8tNi7T6DCWve+MEEmLeRa4lU6?= + =?iso-8859-1?Q?XAFgPATiTR9BGrBBrwqKLye2Pnn6Bx8Hs+R7sFsv6HnQkS8B585+mjXV0A?= + =?iso-8859-1?Q?jXMm+5KDT/IUTiTAeJPwBTNEAG6Yo8gDg+6/9EMuZtQYAYZnM4tMefCwBm?= + =?iso-8859-1?Q?oV/M1vLbCGr7m1BDeRerH34C/2SWa0XnU9zOzqvm6/ery2Cv81aakjQr+S?= + =?iso-8859-1?Q?FdFwyYhZi96v0+HHAeT1Ncyrb84GZVp0kb1VYOBI0JH7TTZy88PMtFfbXQ?= + =?iso-8859-1?Q?nrSZ/VgrVa7hCvBOf2VQnj6iMnNqaJlmnI+E/yXvDNQJn2JDhor7QrClSA?= + =?iso-8859-1?Q?rrCXMDZyWWZhhDrf+VkN7ePKkju46/dqh0NRjqz6571xFdftnXx/b9dli1?= + =?iso-8859-1?Q?+XoZOiqbV8FyrJNCWDLuZRc1gIr0KVbbxN9nggMGa5c8tslnJvW/OTImm7?= + =?iso-8859-1?Q?SEKOX/bZx/aOe9bLlgzQhqdtwBkOJurGSWeDajB/ko2pFUcIYWyMaB6dFW?= + =?iso-8859-1?Q?RcQgdjWDgNNqiUnyvY585ZCFJCfiMaWj8hglJWADRQdLHNSqFAtuZdVCc1?= + =?iso-8859-1?Q?HPXeZDkLqPP+0VfD8EO3A1Fmp+E3kIrykjPJtNslbzwmtL3ATsC8e2mcob?= + =?iso-8859-1?Q?NGBKDmktRjDYG3mhya2XCCiFWaYiig6J/s1ePtuRp3TbBojEAUg2E5xItx?= + =?iso-8859-1?Q?gRGc6bNfg9Rihie4+BZSN+l+ynuYJQ/FGK3CvQYA9gXp00ZtfPwlHx7mXA?= + =?iso-8859-1?Q?gaDydNv1CyuYCOgUeTxo4Bi7N4Rrz72tn9pYxoZ7okujjzLWuiK7etRoRz?= + =?iso-8859-1?Q?JwOHGQklwT4VgMwwLQdXxNR+WMLbOyXjt6bfrKSUHq34oLx6ZVk2F6r9HI?= + =?iso-8859-1?Q?5uaCMLO8dLt3O9rb8FdV3EfLGg+zThKobHlrVJ2WFZLm0xtSsbzC04WLdR?= + =?iso-8859-1?Q?Oqf0F2GVBbFjulBFs9mvdhDXD33oUn5atsgLnkAitzWZH8qgeTOKgCbZD4?= + =?iso-8859-1?Q?WIXnz+DQx0g6sgmqGwa5fkPzRn+NfdGnwNwRyjXcAw7jW5DVkAnzd2OkEc?= + =?iso-8859-1?Q?WrVWN1eIbPedT77yCWDwLAjGBWSrpmI1bZkqI=3D?= +MIME-Version: 1.0 + +Asdf testing123 this is a body \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-348.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-348.eml new file mode 100644 index 000000000..6c9d385d0 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-348.eml @@ -0,0 +1,1261 @@ +MIME-Version: 1.0 +Date: Fri, 18 Nov 2022 16:52:06 +0100 +From: sender@testaddres.com +To: receiver@testaddres.com +Subject: 2 - test with a strange attachement +In-Reply-To: <30fdd5117dd9408487d74e9b50dedc27@testaddres.com> +References: + <30fdd5117dd9408487d74e9b50dedc27@testaddres.com> +User-Agent: REDACTED +Message-ID: <0a5495c56acb49d56545a2017dd1f931@testaddres.com> +X-Sender: sender@testaddres.com +Content-Type: multipart/mixed; + boundary="=_be6bc52b94449e229e651d02e56a25f1" + +--=_be6bc52b94449e229e651d02e56a25f1 +Content-Transfer-Encoding: 8bit +Content-Type: text/plain; charset=UTF-8; + format=flowed + + + +-------- Original Message -------- +Subject: 2 - test with a strange attachement +Date: 2022-11-09 08:36 + From: anotherSender@testaddres.com> +To: "receiver@testaddres.com" + +--- First Text as body test 80 column new line linux style 0x0A --- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor +incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis +nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu +fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +--------------------------------------------------------- + + +--- Second Text as body test no column limit (865 characters) one single line ending with 0x0A --- + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur + + +--------------------------------------------------------- + +Da: From Test sender in another language (IT) +Inviato: mercoledì 9 novembre 2022 03:17 +A: To in another language (IT) +Oggetto: Subject in another language + +--- Third Text as body test 80 column new line linux style 0x0A --- + +At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis +praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias +excepturi sint occaecati +cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia +animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et +expedita distinctio. Nam +libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo +minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, +omnis dolor repellendus. +Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus +saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. +Itaque earum rerum hic tenetur a +sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut +perferendis doloribus asperiores repellat. +--=_be6bc52b94449e229e651d02e56a25f1 +Content-Transfer-Encoding: base64 +Content-Type: application/pdf; + name="Kelvinsong—Font_test_page_bold.pdf" +Content-Disposition: attachment; + filename="Kelvinsong—Font_test_page_bold.pdf"; + size=35648 + +JVBERi0xLjUKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFIvRmlsdGVyIC9GbGF0ZURlY29k +ZT4+CnN0cmVhbQp4nK1Y+3PbxhEe4wAcSXEMgC9IlEJDskWKNAHi/YjTmlbixMm400mqmf4Q9IdO +mqRJY3rMdqb/fr+9A0BSsltl0jiWgLu9vX18++3C7xzfC2PHpz/1w3dvOqtvMufHf3bEsrP9sfOu +E3tBmqaZWNh//u6Nc30D+dzJvTx3bn7AocBxA2yFfuQloRMHiRcFgXPzpnP1QGGqpvNWu9zwI95l +5ZY/NMyu1dN431TZQDF75XbIR/bxyfzm504QOjevO1fjU3s04mcPPprwR065OcfRC7Xc9h7PZ52X +N52vO4Hzb/z9Cn9/rmz+5otOFudOkgZenAYO/s/iyNl+3/nTPXwJ4ILv+YfeBIXvRaETRIXnZztv +FE3XhD9k734YgsKT1j+cOE8m/BKGT/uTxuIwdMIgSWGdE6ehE0WJtC7H5WFchLRRFE6e+Lv1IPKT +aj32M7lOXtbr8LJZF/JBLrwn+TjcrddRwXoTFaGnkic9+/JBFkTVvVmW7+RrOyHf2Cn0VPIU9Vr+ +XSfNIliaihviwikAie33zp+dzT0zEh6mIwu8KHWi0MsSPxXpAKDK7UNDw0/NtHr9cjsYHmkjZmvH +x+bRyfj07PQjypJIwNe/EQf7F/PJoxabOK0R0NAfTdTWeQ2GzCuE2VkYEizCyPNj5+ZvnW+vHsI6 +ppTbuRv6fubF8dVs/pebr+StNYbcNECAc8dNU69I6eBVt9U+Z5OLiTJq3UacG8DaGCbnXhYK4XKr +l1flnC1U9rSci9o7GhhmOW9burlEGbmua93dIMVJFpPnUeCludBle8cn9sxe+YFP+whE6iXSptWJ +PR5zHn40RVk/iuK9AoWkW6lyU8EwdMAJIYiC4LPZSbCyIY5wGKrFLxIsggusS4vjshP7dGSvTk73 +DMrCWklC7NHCNSkzFW3I/dmQ48fBlXFeSz/RehbPVifc9sc+H53ivzHuvSy3+eF6YJ/IwO7lIZLa +gtCvI2spjyfnrb1sJzEikvt1mp70DT681AY2s6d2FS95ckYZGS/O7mTvbpiSmh+ZouPxgCQFR8KB +29zY2L6PXHlzH0EeGhaMemCbdlMJ7wj9eQL3UKsgHyrTMBJlKjoBTn/29r71crcJIHZwJwSzRE25 +PJV0GWWkBULCOgG7EEhP42rJUkbt1tORFHbDMKXCk1s9e2i64kAu0F7p8Cbn5aYpDpRW5lX6v71a +6ZbZ1bR5mCcwMrwanCtUsL4oOxmJThEHDavFVErpr+KoD3mfFLkXFLJprPTh0fD/R0MBPIyE5m+v +hqzctANUc7lRFdaau1GQo1sFRBrqZFRFRlu22Dk2izBKKMSPBZtMtMcT7UG5QWoEkVVktIfPMI/p +0ZWNDdEuyk2/D/Hw7OyC4+Xi44lAdZIWXlan1WE6CHmOMuVRuVV01Dmh2rP5YMCfXfLLgmfc54KY +Y/IoK2rGaZfbBRULId8Cqes4/NQt55qhfmIx9U6VijBF0jZ40g4jtNyWFqMqzu/2Z2qn9U0X0+SC +HOH0i4dH5MwZt8fBjJ963sgO7tzlAkShk8Y1BVZ8MFMYGIFiv5teBkFLRUa8ybSF7h/74gjWh61p +65EyUrBYSc7KTUJv0q7XB40l3YkZqPPJND0YJWrMYpRoWvFvgmycpV5YzTmI4DRSdyFs0Jj6OBNV +cLCHI0m+hWBJt+HK0UyQjRuHxI7N8tQR9Ys+HtcFPxsfz2bHo9Ht9ukmkU92+tQMSfCs3C6BorZm +cB3gUvH70ex0uTwnHDoAJf/dA+fJ74e8P3mGThLMfM8Dw99xwM0Ep7iN4mflxkbjGVd9JAJt1bYJ +J5IiIZsqShmPh1h2iyxKvDS9su19Lgn8YjdSBRgYwqQmk4OtN/I1imIxNP2CzCGpmJSQVT+u5q4i +yu+b1PdN4kAH3EzywAsSmdOLZds0VFN03IaNwPu7W2lAvP+t74NSBPpFQWeJl1S3LhbZaTkXoQ0K +3ILLajgMFVWUaz3FldvY1Iz2+TSqhuswIaCIynmfaLkdVbIoFKk7pe5CunfXSjcL0FMd/jjKgPns +3h8HuZMeOBkjqIfjYEuQnG7ypWbo7Dlfg8DQu08t2+bycTaiZ63ema2sVbMV1M8vmLJmBktTU34o +rbUe9f1n5gA8igfF4qO9CaCcD0w5Alh8qvVQF9uFyRVT4SDc+ULHjAe1eFm0NfDR1tA4jWiMmwaZ +y/VPmLbGPUuTrxnXFgvNoAPdLluUWxX70IRRkVMUrwbMNBQSpDc5m76mcVNRmc7apsUnUik0lfPr +ayyaH4jD6kNxIDGLI5kCW/IOFKzoEU0Lso4eAgJ5uT3CbKMVxkODmx9jqK7qXBwRJ9yomar6pnKt +GUQf6xemsWaK9pxTYPXdOiJdbeG5qxHPdDWFiYDwB9OLJ2Gfa4pqmByWjsYIofQB0UW3Y0vsmQda +FioCat5O6/8Yz812u5zLO5cayV/DVdLBlU/FuHosx9XPOFNEVmTKEfOl7LQw4rZBh37W5klfWI+D +SJfS3nL7kvWYKlZxQkU+VbwtGFRCyvicVvUekEV+ML7QFOyJUPEBUKVdXwNmTEZBDvez1SjguqVb +EBZWmMZSE/60DQ3nAVBpj0g7xgABKqRroQ0A+OecVfYJXOn1OqXIBBhpga01At5CAlhJaWpm+KxQ +eBMbXEVTtSC/S4MCZQ4RQGgxqLJkjiqD/ZktDB5ynCFZhZzldX3DN36JQkCYkCaKzAJVRJesSRal +ReFYM3VXvUQJhJU5aYOXV3Ca9Q6qiEK9kOSs8WumSNjIxDUeiwWBqtrkHazoSWZf2UHww0EoNwup +ViZ759AXdI82EBuNCcs261WfXI0Z+ifamqxCfna2P7MKi6/sI9s7Gtn2ichpEIjvXzg5BZv0JQSY ++vlzSsAOvSJGxFwNSKqaa5sqgAfjVcR0Lutx32Kyprh7WtIeUkMRBf0ttFupM7tdZJ+KhUiQiA8u +HQajbZDQWkQbFmDqaAuokSrMH3CuSaCgfRJblHNz72a5Ullg0aenqCi40DW5ORCwRnGpIgiVx5JU +CH16XcXANshIFXMx0WsPRQE6rkE3pOqSnixUgvZ7vNAQRbLG3AUSO9C5XYoy3CF1P44EV6rzVEJO +jrhicILTuMMU8NBUUvFcEEFPRh7fq/MKMTBYTvQLlOaCSWrBZ5lB75wiAqwqoihuswLwuNNPgBFd +UVsIEmJoA5WrIkSR2TMJ07sOUs+SqRw58oi+UaoeMjP40tS6bjVQHA4KzWyNQeFXzNZ507P2RgXx +hZ/GRTMQPWHLlwaB45IZ9URLXzqiRYuYHfQyNw1SD99geVx3s3Lz37iX3mryHc+O8GPEdf0QE2vC +iqA3kZ5tlxKnEQx7gqbXjOyQvbxpWGSyWGgTpEQdANY6uxbM0+AICoABahI9QOJVw+WvhvzVIQW8 +gsJXInt9SrLoZyLTryy+y8f9/z06iJ1M/DOsWMWY5xVFkRbNbwr+zTdfvnjt/OGPn710XOfTX376 +7h/O37/HiP7D263z5i0eftrg8c1f//XT283eF/t/AGaEuvFlbmRzdHJlYW0KZW5kb2JqCjYgMCBv +YmoKMjY0NgplbmRvYmoKNCAwIG9iago8PC9UeXBlL1BhZ2UvTWVkaWFCb3ggWzAgMCA1OTUgODQy +XQovUm90YXRlIDkwL1BhcmVudCAzIDAgUgovUmVzb3VyY2VzPDwvUHJvY1NldFsvUERGIC9JbWFn +ZUMgL1RleHRdCi9FeHRHU3RhdGUgMTYgMCBSCi9YT2JqZWN0IDE3IDAgUgovRm9udCAxOCAwIFIK +Pj4KL0Fubm90c1sxMyAwIFJdL0NvbnRlbnRzIDUgMCBSCj4+CmVuZG9iagozIDAgb2JqCjw8IC9U +eXBlIC9QYWdlcyAvS2lkcyBbCjQgMCBSCl0gL0NvdW50IDEKPj4KZW5kb2JqCjEgMCBvYmoKPDwv +VHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIKL01ldGFkYXRhIDI1IDAgUgo+PgplbmRvYmoKNyAw +IG9iago8PC9UeXBlL0V4dEdTdGF0ZQovT1BNIDE+PmVuZG9iagoxMyAwIG9iago8PC9UeXBlL0Fu +bm90Ci9SZWN0IFswIDAgNTk0Ljk2IDE1XQovQm9yZGVyIFswIDAgMl0KL0MgWzEgMCAwXQovQTw8 +L1VSSShodHRwOi8vd3d3LmJ1bGx6aXAuY29tL2Rpc3BhdGNoLz9hY3Rpb249VHJpYWwmcHJvZHVj +dGlkPXBkZiZ2PTExLjExLjI4MDQmZj1Qcm9mZXNzaW9uYWwlMjBmZWF0dXJlczolMjBVc2VyJTIw +aXMlMjBub3QlMjBpbnRlcmFjdGl2ZSZyZD10cmlhbCZmbD0mcmZsPVBSTykKL1MvVVJJPj4KL1N1 +YnR5cGUvTGluaz4+ZW5kb2JqCjE2IDAgb2JqCjw8L1I3CjcgMCBSPj4KZW5kb2JqCjE3IDAgb2Jq +Cjw8L1IxMgoxMiAwIFI+PgplbmRvYmoKMTIgMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JT +cGFjZS9EZXZpY2VSR0IKL1dpZHRoIDQ4NQovSGVpZ2h0IDE3OAovQml0c1BlckNvbXBvbmVudCA4 +Ci9GaWx0ZXIvRmxhdGVEZWNvZGUKL0RlY29kZVBhcm1zPDwvUHJlZGljdG9yIDE1Ci9Db2x1bW5z +IDQ4NQovQ29sb3JzIDM+Pi9MZW5ndGggODU5Nj4+c3RyZWFtCnic7Z1PrF/Fdcfv29kKErY3cfAi +buxKkQKKI2ErSOFPFk1MKwVbIqHOJhg2UIjAKZGC8w/yx1RKGpME4mzAzqJxaSr5gdTEJgv8cKVU +BglXGDULE6gUE7qxXYnG3rmHN2RyfGbu3Lm/371zvnfe+SiKzHu/97tz5893Zs6ZOWfh8uXLDTAX +3rl052NHnv3335Z86NXvW/Xmv+xZc9Wqtg+8+fYFKtXSqTcLFupdXnnq3i2b1/v/XDzxWyrG//7f +pcLFMAyjPC/8cPcCuF7f8sDB8rJIHPzKjjtv/Vjbb9f89WMqKrn//u0PfvYG9+9Dv3pl9z8sli+D +YRgqfGH7Fmi9pmXsX9yxv/xzP/j+NbS+bvutolCe/7eH/apfayYzDEMF2l5D6zVt9n929FT5537z +zlse2f3Jtt9qCSXNroce3un+rTWTGYahws1bNh5HtodceOfSxs/tVzE7vPHMno3r10R/pSiUL/xw +9y1bNrp/P/jjX/3wX/9DpRiGYZTHWWhx9VrL7HDbJz68+N1dbb/VEkpuolGcyQzDKM/V71t14ZcP +0z9w9XrL3Qf+88zb5Z975Du7dtz44eivFIWS+z/N02gYK4oHbv/441+8tYHV6+On3vzkAwfLPxfT +0yjOF2rNZIZhqOAttKB6jelp1BJK7mk8debtj919oHwZDMNQgVtoEfX6wjuX1v7NYyqP5gfmBIpC +ya/JUOVsuevAf//PBZWSGIZRkgdu/zitIL0oIer147/4zZ4njpZ/Ll/Ghmgt+T+6ef2pp+4t/1zD +MNBA1OuNn9uvsn7kB+YEIJ5GwzBWMnB6bZ5Gjj/H46Bp45GDL5wyZ6Nh1M6aq1aFB4vh9HrHVw8X +ju7k4KE5QrSW/P4cT7NsQN+x97BZrg1jhRCKEpZeK94eTHgatZb8zZU3LbUM6IZhqBBaaLH0mjb7 +jx46Xv65mJ5GFzHA/VvxzIxhGOWJWmix9FrL7CDiSnMUhZJ7GrVmMsMwVIgeNADS68UTv935tcPl +n5s+MKd1uFDMrlozmWEY5WlLmQKk15ipCbSEkt+01JrJDMNQoc1Ci6LXWp7GdOovRaHknkZLTWAY +K4o2Cy2KXmvFKU17GrUOF/KIAZaawDBWFPyggQBFr7UyIiY8jYpCyWO6mjHEMFYOtONf3Ler7aI1 +hF5r3R5Mexq1jmSE53ge/8VvLrxj2QkMo34e/OwNbebZBkSvzdPISd+0NAxjxaKv11pxSkVoDoGi +FULctKT6scW1YVTPxvVr2tLGevT1Wuv2IA/NEYKQBN1Fd7K8uoaxEkifVXMo67UlQRfwiAEWMMQw +VhSJkM4OZb3W8jQmTsw0lgTdMIzipEM6O5T1WisjYtrTqHW4kJdK6x68YRgqpJPHOjT1WitOadrT +CJIE3QKGGMaKIhHS2aOp15hJ0BE8jYoRtw3DKE/6orVHTa8V45Riehr5TUvzNBrGiqLT0+hQ02st ++ywPzRGCkATdAoYYxooix9PoUNNrLfssD80hAEmCbp5Gw1hRpI8/cHT02pKgc4T/U+vCp2EYhaGx +/8juW/LjT+jotVac0rSnUetwYfqmpWEYhkNBrxXtswlPo+KqNlEqwzAMj4JeWxJ0TvqmpWEYhkdB +r7U8jYkTM4qexoT/05gKtDmj+b6wMc3MaCuQ0nqtFac07WkESYLuoMnjVMGRv+aqVW0ZdowcFC83 +XV56VOW5Wrz59gX6n3YphiEnempIab3Wuj2YTgKAkARdMXrqPBkSii0tw2RAJJR37jtSuOHCYmhZ +0oR9T2WNPx60lDn19L38fjYtqh45eLyaCGg50VNDiuq1oqcxcTdfcX3EPY26dxpnM8sUblBeXSA3 +UUFC7yreFh4P/oJVXiLLP3btKarXmEnQtYSS37RUH2+zGUNLNqhwzGr1JbG+BknyWd8dK/GCWs09 +Hvl3GjlF9VorTmna06gllLxU6uMtnXq4jZINyhcjIDdRGz1LGkgxxkPY6LSkYzxyoqeGlNNrrduD +k/A0Ioy3nHCOnJINKq6AgtxE1XKeC9OnYq7R8eC9Uau5R2W2Wxfl9NqSoHP48gEkempfE3bJ66DC +XANyExUh9G6jd1t4PMQLatXzeKSjziUopNeKSdATTliQJOgg0VN7mbALNyhfjIDcRDWH53hwU2GV +4XQyo6eGFNJrkDNPAq2FCS8Vznjr5QAp2aBiMQJyE1XLAyaKoeXwHA/hSgFZzQzIbJ5GRwm9VvQO +8ZWIAOQkFtR4y7SpFXbSckONon9Y2ItU9JqG+uK+XbxL1+eIA3Esj8c81x1K6LWWuyB95kFLKEWp +EDyNnswDoSWdtCAH18I1EUkJFaZkGdZctYpahxv36nPECQNmfS/Y9Hfsc0roNWYSdISTWGie/cwk +ciWrThx7QriJikN9jjjRA6FWM4OQOcTaGF2vFZOgJzyNIEnQ0Tz7OZa1wnMMX4yA3EQFAcfzMSC8 +nkHOTQ1LwkKbw+h6reUuSJ92QDiJhTneOoWp5BwjFiMgXmsX6aVkTC6CBrnoz/U54oQrtb4XnO1W +GmdcvbYk6AI+u0J5Gj1pI1LhqgOJICEidWy564DKJp13niodccLTWF9ElBkChgjG1Wst71A6CQDI +SSxMz37avlay6oRxZoVH6hDFqM8RJ+6OYq5m5mG2gHyCcfUawacXoiWUvFSw4y1twtYKGNJg3ERV +LIZweGr58McDxLE8HoPklxhRrxU9jXyiFoCEnkD27Le5RAoHDEEIkSGKoegB437XKq/8cQMm2rmp +QRjEZT2iXmsdfsD0NPJSYXoaPW3n+Uuu6UAiSGA6POtzxIkrrGjnpuZnqDStY+m1JUEX8FKBB/ON +BqMpXHUgITJAilF9agJ+dxR8NTMb83saHWPptZa7IB34CiT0BKan0RM1KJWsOpBIHZaaoAyWmiCf +sfRay12QCAoKkgQd1tPIESbswms6sRhB8A83MM7z+hxxlpogn1H0GjM1AUipJuHZF0Oo5JoOMzUB +yIXYKq/8WWqCfEbRay3vUHoe0xJKXqqpePaFWankmg4zNYHWJl106foccSCO5fGYOTVBlOH12jyN +Apwk6Pnw1WXhw1WAqQmaZYsQaWXhMpBS86j2VTriQK6wjkfftE1phtdrrZUIpqdRJEGf0B1ib8Iu +uaYDiSAx1OmrYanvyp+lJujL8HptSdA5vFTTss05E3bhJY9ITYDgH8ahPk+jpSboy8B6DeLTE4DE +fJiEp9Hj1piKAUNAWq1Z9vIdf+WNkmXYuH6NOK47rck+B0tNMAMD67WWJKXnMYTQE1P07F9eerTk +bgkkgoQohpZ9TxyprM8RJzyN01rN5DBnaoIoQ+q1oncoMY+BxHyYom2OVpolFRMkVj2gw7M+Rxx1 +reM/2o3Q3CNBuwd6wXlSE0QZUq9BoisIEEpV5R3iYQEJkQFSDOE8V7zyd3OLT2geSMVoB8MXWFr1 +TNPGxg8MnzaI5qHHv3jrsJYQx2B6reguwPQ08v1sfXeIBwfkXBdIpA4Ev+tHN6+nqWvwFWKIVj0/ +cPvHxbSBz2B6jelptCTok8BSEySKoTWyiqWsVKlnzCObnQym1wg+vRCEmA/12eYGByQnAGYxVBxx +JeVMpZ4xj2x2MoxeYyZBBwlyP0VPY0ksNYEAITXBUPE/O1Fp7sGvsRRjGL0G8Q4JtIIt4CdBhwIk +goQoBkLnafRG1uWlR8s8SKWeBwyYV5gB9BrEpycACWNS3x3iwQHJCQBSDBCH5/77t2/5yw8M+520 +aRCjVauei5nmB2cAvdZyywifnkBLKIXhzzyNaUQjgqQmAOnS9R0rEgsslUE6xjWWYgyg1wg+vRCE +UlWZNnRYMFMTqFiNb/vEh0lHuDOmvskeITVB4vgvPvPqNYh3SAAS5L6+aMXDgpMTIMx/RpJ94Z1y +UhLaCqo8VsQNESrNPV1Po2NevQZxywgsCfokwExNAEJ9x4oQHMvFzr2MxFx6DeLTE4CUyjyNnQBG +6nAcL6sj9HRRgCone/UrrOlN+SSYS69BfHoCkIQJ9aUNHRbM1ASkI7RlLLzMD3WkvskeIQn6pD2N +jrn0GsGnF6IllJNLgq4LSKx6hEgdzQpLgq5Vz9M9xueZXa+hvEMekDAm9UUrHhaL1MERXbrKY0Xq +SdAnGjBEMLteI/j0QhBSs1dpfBwWzNQEWg5PUYz6JnuE1ART9zQ6ZtRrEJ+eAMRnpRiteCpYaoK2 +YlQ52XNPo0o9T/0Yn2dGvdaSpPSmBiSMiXka0wjHLEirWWqCkRBaqVLP0w0YIphRrxF8egKQhAnm +aewEJEQGSDFEl65vsheeRpV6rsDT6JhFr0F8egKQUtVnfBwWS02QKEaVkz33NKrUcwXH+Dyz6DWI +W0aAkJpd0QY6FTBzAoAUo/oc4Sr1POmAIYLeeg3ilhGARJev7w7x4PDqAgk+A9J5qpzseUA+lXqu +xtPo6K3XIG4ZAYLPStGAPhUwcwJo2WTEydT6JnsRHlalues4xufpp9cg99AEIAkTqjQ+DgtITgAR +hZn6D0lJ4TI8ePsNvD9XOdlzrbSAIYPQT69BfHoCkOjy9RkfhwUzNQEI9aUmEFppqQkGoZ9ea7ll +EncaaWGy5a4D6mFMqjQ+DgtmagIQ6gsYguBprOYYn6eHXiu6ZWh9fWhvZJ588w/nH/zxUZVhb0nQ +eyGqCyRSR7M80S6e+K+SZSAFERNGfakJxFEuCxgyFD302iSJIzyNWgb0qYAQq74JNmpankZxwkzR +hy8ykI2EpSYYily9NkkS8K1WfcbHwbFIHW3F0BpZxa5oq9RzZcf4PLl6bZLEsSTovcBMTQASA0dr +jc+Pfo+KSj1XEzBEkKvXJkkcvtWqz/g4OJaagIOQmqDkwQkVx3J9nkZHll5XGUB9ZoTPysz6aUCS +oINE6gBJTVDsirZKPdd3jM+Tpdda99Aw4T4rM+t3YqkJEsXQGlkibsl4qNQzzc2nnr63pmsynm69 +rjKA+jxYEvReWGqCtmLUN7LEsr2+SwniZmx5uvXaJIkjwpiYWT+NpSbgVJ+aAKS5xyOdjLAA3Xpt +ksThPqvCxkcSncn1fuHis9QEdacmAHEsj4d6aNYOvbYYRhzhsyppfHSPnlYyBEtNkChGfSNLuFLr +OwGMcKa7Q6+nJRBjo5gE3T16WrYpzJwAKlYI0rLFfbv40qy+kSVsBfXty4s5aROk9Lo+f8ic8CsG +haXT+ammddYbMDVBs7xPp6Vf4WLQOOdlqM8R18A4lkcCJDRrSq/r84fMg2K8Me7GWbj5m2UeOieY +qQlAqM8RV72nEaQjpfS6Pn/IPCgmQed+qqmchefVhZOaAIEqHXG8i1a5LwfpSK16XZ8/ZB4Uk6CD +uMt6AZKaIIyo+cjBF46XtRpvXL9GrMvqG1kgjuXxwMlx0arXli2Fw10NhZcPwssxCdMnZmoCrS4t +DoHV54gDucI6HjihWeN6PQlRKIZwNRReLYZx1MDtVJipCRSLAZKLfTwQHMvjEea4UCSu1/W5C+ZB +uBpKymXUywFuwsZMTaBVDJCrleMB0tzjoX6nkRPR6yr9IfOgmAQ9ep8K3ITNq8sidSCkJhgVEMfy +eECFZo3oNbgcFEa4GhQ9jR5kaxVIagKQSB2iNuobWaKL1ncCGC0JZESv63MXzINiEvSElwPWhA0S +QcJSE5RBOMNhu+XMiJAv6ki9rtIfMjOKSdDT96kwzaAgLj6QSB0gqQnGA8SxPB4IAUMEUq8xhUAL +kZqg5DItfZ8Kc2wIzwxITgCQYoB7iWdAdNH6TgADJoG8Qq+r9IfMA3c1FJbI9H0qTMcOSAQJfrzM +HJ7jAeJYHg8oT6PjCr2u72LSPAhXQ8nlQ859KjRjKEgECZDzc6I26htZoovWty8HCRgiuEKv0SRA +F0xPowdthACmJmiUjmSQWNNQ576H+hxxII7l8VBPTRDlz3pdnz9kHhSToGdGboQyYYMEOYk6iAoH +DKGGE4YsqJYaBBDH8ngAehodf9br+vwh88BdDYVXi5n3qaBMoiARJHDiPHCqv/JX374cITVBlPf0 +GmrwI8BdDYVXi/leDhyPPEIECZCI8oIqRxaIY3k8wqA9ILyn1/X5Q+ZBMQl6r/tUINfJMFMTnDrz +9p2PHSk8n4WOYjQ3w/yAXGEdD0xPo+M9va7PHzIP3HVWePnQa0cP4nIAiSDBj5eBFKNKRxyIY3k8 +QFITRHlXr+tzF8yDcDUU9jT2ityIMFpAYtWLRZ9WMcT6ur6RBdLc44GTmiDKu3pdnz9kHhQ9jTPc +p1I3YWOmJgBxeKq3zuCAOJbHA9Nl7Vl44w/n6/OHzAN3NcB6Gj26JmyQCBIgx8tWQmoC3kVBzHED +gumy5iw88KNfIvisQABJgp6P7pgBiVVvqQnKAOJYHg+o1ARRFq6+dV9l/pB54K6zwuuj2SI36pqw +QVx8IJE6hJ9q4eZvqhRjPEAcy+MBGDBEYOvr96CtEK0duGKSFG6560CB9XX46F6cOvP2jr2HC5sR +P/j+NYf27hQXdsuba8NigKQmaOq6JhPtojW9YLQ/A9KaH90wJgdOagLDGAPTa6MeQByehjESptdG +PWjt0AED2xtVYnpt1EP50zK0sn5k9y2YsYGM+jC9NgzDmAam14ZhGNPA9NowDGMamF4bhmFMA9Nr +wzCMaWB6bRiGMQ1Mrw3DMKaB6bVhGMY0ML02DMOYBqbXhmEY08D02jAMYxqYXhuGYUyDhd///uzi +kWf9f2/btnXrtuvFhy5evHjs6K/Pnj2b/hjx4tKJV1897f9z8+ZNn97+qaHLXDmLR57zVb1hw4Yd +Oz8z+CPOnTt/7OjzZ8++Rfgfbtr0odWrV1933bXRljWMYlDP7BSllcnCw1/52qVLV8R3333XF2jQ ++v+kunv6qUPnz58Xfyk+Rjz5xIHXX/+d+NjfP7Rnw4ZrBi1zzYR1uGvXHcN2VppQDz79s7bfbt16 +/a7P3zHg4wyjF9Q/D//8GS5Kq1ateujLX1q3bm308y+dfPno0edpabgS+u3CngcfEj/69Kf/ii+K +oyocfoxq7fDhZ8Rn1q5d+/Vv7B2utJVDU+M/fl/mxBtWr2mr9O1v7RMz9HiPM4y+kFi/9NLL4off +3fct2vzxn1BPPv3qa6TUbil5zTXXPPTlPeVKqUSHXkcVJPwYQSoQrsFt8PciOud97et721YWQz2C +Ew4MwyhJqCThso90idaRfNlx0003jmE5RKNDr6NznYNXUHSLvUJmvAEJa5t2gvse+/aoj2j+NK2e +OfM6rVmEjcswSkI98Kt7vyF+KGx00T3iClkaRvTaG6bPnTv/nW/va/vLTZs+dN/997p/R20mf3ff +PZs3bxq0tJUTriyuvfYjd91956iPMJuVgUN05ce1mFbWtObgfnLHCvG7RPTa62xicd0wvY7aTLia +O+hjtBmnRVxY1/Rhdyyh706cZloqJP0//Zv+lhos/AZ64otLJ9xniB07bxP+z/D0y67P/y03QThL +GfUk+ioxq3eWnF755MmX3L/pM0586atcVdC3kVxu3/4p+oboymLHjs/cdPON/j/pD6kk586d8z9Z +t25dZjd1R3fCaZWW8FQh9Bb8Qc3ybE1/ErYXFZi6BxW4bTKmF1k88pwvpHPu0w+Xq+Jl921Ub6KS +Q3jVNbGGC59FUA3ztnDPDV+c3prKnz4M01kA8QHalfI64Z2ToOqlx7nO5ms1HCZtHDv6PP2V+7c/ +NeRe7fTp15rl7Sz9kBfA/ZbGXThDuxZPL0hdZ6OHij9PVx19norq/zM82pH+ALXmiy+eEN/pzyyE +ZhAO1QCNhXB0tw1eVw/ULhNaVrbqdXpx3bCuFpV1vrh2gyoh/Q7qB1TdvfbjTz91yHVWR2iBoZ5x +7NivxVO4r5lek3qA6JHcIkSadfTo8wkHnftOkomw1cOnk/6SmggLsrNQR1cWvhrbTulkLiuiw0Dg +R0Vme1EHEOLo+P739guJp28Wa6LOYofdLzwkQCOQ6iSxL6b6X1o6kW47GrT0FuFMENaYsE1Fu5b/ +AJX/+9/7gTjkQPuYJ5/4Ka+HTKtrWBh6TXp93kZ8n9S2CBXQeLnv/nvCFmzrbJ1/HvZh0WrRTs6P +kIU7dV+r9L4/efKnnUXiChAeNYkyobV5q16nF9fNn/Q6Kut81ZDZ9uLpmR8OW/cH+7/n/93WwHxI +R03G1O9dL+ysBP5X9Mpi2IfKRf1J/MSP2Kikutdp63b5Nru9D3+9s9e6YZNewgjCCTJa59QfRDN1 +OlGjuw3RN8LWJ82i8lDb0Z8LZUwQPS4WGo7Ey4aNy/U66tcVrc97Wpov7fly+qsa1hk6Xcrie4Tm +5siiRyidWD85+JCMfoC7uMM39SbBnDUHV55e9SBOT8AS12vaZYerG6pT3oNd1YSrjIaNq3CVwf+c +pCH8VS9zatiEfK4OR5TDt03aBJEv1tGSR79cwEdsqD6JGm5bFbbRqddOjDpP+4WIjh4trSBzORMq +JtfrqKx410vbIdQ2hF0iugrhxY42Lnc25IhLpkbkCKjve20i5axe0Trp1FyqHFftJ0++HC68uByH +3UxUbPgBPgtG39TXUs545JdCot4gqoSLFy+dPPlSaBuZhBcncl+GRgW1uqgaqjWqTd7ebjscDu9O +PyR9FQmiE6lotw5v4rTx4tKJxcXnROFd30rMrr4HhOLie0+061Cn37nztrXr1p4/d56aPHw1vuBN +X0sRJWliKwtaer9rfg36KHW7qKU+QaIw9FLbtm11a/zo8oca1LXX6VdfCzu6sBJEv0GQeUIx/Cpe +XW3TWxPrFc3ygNy+/VPUdm+dfWtp6USoO3ym7/R6RT/AnQ1tawVP/uI6Zwp0ZYsuj1yndSWn7kQF +S2huOA8JPXWmZzfErtlwDZV/w/L/Ny1+LN5knbNgevGXXky4Xup1IywMfxA1H3USV3j/IpOwYi88 +8eOfiH5Pchkaoahv0fgRek3jPNREX79RyRMHHqJNmL83CR/hnp5uWleG6Gd84Tvvakb/nL9d2zCj +enOOKepSJFuur+dvQmdeCESVlLtocvzG0VmQL3vbFvLUplu3baX3padkbgtC2fUdI31QPVxYhU6L +dK+LLiP4NNOpLNGtFRWD5oxrr7t29epVVIbMemibAqmzUYGdCct9VeKwpv/PdAtGf0vzEClap5xF +p0m+9op+OS9epzklOk1G/V5R7wLNW/Qik75uHdHr0NrourKQMPoY9TkxMPjwjta+a3v+k8QOqJNw +YLiel96NttkZvCk5qlzhLj6xxIv+tmk/n5ezhhKF7EtaYpoWkRIm47QFqe12Vf6GiRPOYb5jhIrs +fxUd0mGPCte/vGnStummpXG9srTNvrPFZohOgdExEn7SecL5T2h7Eapqeo3lcQcq6JM05YQ7pM57 +idEP8DpJW0uajCW8Jzp5ZL4IMhG9FviNW45JLmep1Ukv2794CmnHps2bRKPSUBTHSO67/x6xOub7 +02hjh4MtrdehfSOxBc4xI/h3me1EdufiJXyd0J0YHTBer6MLqHmc76IOXfWGT/FuxqZlWgovbSaO +unfapsOCNVc2fbQMs3m0oluB6B6rl59QwIdtpyXHEa4bOj200X2PnwWjXUs8pXN758n3xEzrYmS3 +XiesvQKxdw77dCa9rioJlQnt7E4lxQikR4iGF+fAwjfl0uYIJyQ/qqODJ6Fcvea22W6od/qCogZ0 +0ZXThw47F1B9EdrhChwOe75+z5l1oors+3m07bhtOqoaadt6M2urtRkoxGH5tmJnwuczqhxh+WyD +d49O23T0A3wWjL6p2JllhhZxZB5qbCZ1N7JDr/mSsFOvxUQXjn9aF+R02ejNiDbEqr/tnJMY5FSS +8KyL/8+cNVra49Rpy+MkgrREmWFFkLN4SRyl8qQHTLg0m9PtLh7nbieJihWFTBzg9aSlodNwFJVj +3rjR43ezxWaIVnhU+qN6Tc9dvXpV51PCOzvUYU4v3zGJHuJy8Irt9NBGX6Qz9IV40+gB2XTF0iuc +fvW1s2fPJlQu/9aSOh16zSs0rdfhO4e9doxz6ZmlSh/wEmvA6HeKRU102+i7V6fxgdN2lMXJU3hb +Z4agIjmLl2jELj5LpR3IOZEf+hJOe/Tu6Uib0WHP3zS6U+ZVmnA1J24S+YrKt7HmkD8Fpg84zgO9 +9fLJkF+HHd536fSQabMm81mwM1JCjp0qDa3xSbjDqwz16HWnT9wTWpFCzRKjy0cl93+4afOmde/S +Y9uY3gZ6IU4YiMOxFB1yzr987XUfuXjxEhU7/DauTZ2eE05UYnxHjFZ73x1czuIl+hl/miV6mbBh +7d55xG0GOvf4Ydu1xfV1l/5pxNJbhLrDvyc6b7lTj+FxRv/9Xll6ba3S9JoCox8Oj/fQK/hzbO+O +tHVr3YE8l7/C3Z53a2ohl+n7nNFJzp2HiZ6edCTOEYZv2tYZaJtIo/L1M697s62/uO+KJCoh7OeV +6LWor4ReR1+47QjzzcuHec8tH2FOjP9MEvfm+X6/rfDcVcWJDtoE3HAULVLCiBH1w/hvi04efffX +OWGeZjCAdh6enT9bRcILEl1pznDlR9zxm8Hvwuuhl401Td8psG3GdVNFW/QY19PajjO5Z5Eahjf7 ++Vv3vaDUXCkaOW/aeXbFdYaoK8hpOvWN18/8Ljw0MSX79c//6Z/bbg2J9VeivtpEtu8VwdkqLjrA +xGGMNr1uW/j0Ei9xGb3znCknJ8xTtAvmS2H+Mq1Xe4lJOsdwPAOJ4wptva7XReQwkEDfqbq5snE7 +j0nk03cK7DtX8XfvVWlNMMnlH3DydC6nwjdNuOV9f84/GuuY0OKaWDj6q2PR1wvXg21uscQLuxBl +OQ3Jb2H1JdpXhD5mBhHkUA8+cuTZzt4fRgWL9pi24wHRiUH01OgL5nsdOw88cDIlO3x64rTMPLSd +Ik1/eab6RENWJY7uut1hWllyjtlkErUopqfA/HA9YUiD/Nk6rLf0+oY6W+LQd5M92Se02PfnXqFj +SOWpaSaUoGPhj3/8o5DUhHSKYeC6b6cjhUd9DKF+s23b9e7y20yvIE8ghYElw8I7y1qnadXlpaXC +R1WbJCMaVVLc+o2GguLwYdkW6i8dKaUTMfLT+xh3Wze6vaXi0StTi4eNJfrGUCMhqrzphH4OUi56 +izYBcjv9NstbNDiff3Gua2HjCk2Z53iviL1FHZv6Rucwoe5HLx6N9eG/h4Zt2wBfWjqREDuqN/rD +6JY0ur7xlzDF6BMKk/mmibOG4u5xugZcayZiAsOycPny5WIP834Ajw8+AI53xXgm19J9ofelt+Y/ +8X6qkrSFoMk/bhH2upy2E68/xeYOW7CZ6d0dma3Pa3uk0U2rKB7xvGl/qeiL9D3RAEVRvTaMTtzJ +303LQWCiy/yphFIzjMExvTaw6HstyzBWDqbXBhbpMDXTivZgGMNiem1gkTjJO6G8TYYxBqbXBhbR +9XXmSSTDqBvTawMRfiBH5VyKYQDy/x/DPzUKZW5kc3RyZWFtCmVuZG9iagoxOCAwIG9iago8PC9S +OAo4IDAgUi9SMTAKMTAgMCBSL1IxNAoxNCAwIFI+PgplbmRvYmoKMjIgMCBvYmoKPDwvRmlsdGVy +L0ZsYXRlRGVjb2RlL0xlbmd0aCA1ODU+PnN0cmVhbQp4nF2UvW7cMBCE+3sKvcFxl5RkAwYbp3GR +IEjyAjqJMq6wTpDPRd4+M7NxihRjYI4/u9+szPPzy5eX7Xrvzt+P2/yz3bv1ui1He799HHPrLu31 +up3Mu+U63/86/Z3fpv10fv467b9+763DhraG/za9tfMPj18szsy3pb3v09yOaXttp6eU6tO61lPb +lv+WRo8Tl/Vzq9VQ6vsK6zWUhkabaygNj7SlhtJYaPsaSoPODjWUhkw71lDyRPtQQ6nX6mMNpVGr +Uw2lYrSXGkq+0M41lMaBdqmhNGhzq6HU66q1htLosIYsKGxeacFq4nUCGlgteGdasJp4C5s0sJp4 +h5EWrCZe12awmnizCoHVxJvZhoHVxOuqC1YTb2aSBlYTb2aSBlYTb36gBauJt6gQWE28RW2A1cRb +dDNYTbzOswhbQhrsysHqwcu6DlYXb5EFq4t3lAWri7dnVw5WF29h7A5WF29hdA5WD15OAcUlXCUL +Vo/58ttwsLp4RwbrYHXxFmaFOCXkzHFj5hI2kxeDklBIbYDVxZt5FcKWYFkIvUiwPIvJSCikVbDm +mC/DQfYSeCdasGbx9iyEahLa0CpYc3zPF1qw5uBl7JiqhJuJkMGa43vWZrDm4GWwGaw5eHUWrFm8 +vXoGa475ahWsOXjZBgKTcJZX4d9FQlc8CywJq0TAVyyldGHOKC7hKnaFSCRsZhoYspRS02awFvE2 +toFeJBRyvSyfTwgfGb5Wn49TN38cR9vuetL0ZPGpum7t36u333ae6qDTH+WnOLQKZW5kc3RyZWFt +CmVuZG9iago4IDAgb2JqCjw8L0Jhc2VGb250L0dBVkNCTytBcmlhbC9Gb250RGVzY3JpcHRvciA5 +IDAgUi9Ub1VuaWNvZGUgMjIgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEvTGFzdENoYXIgNzIv +V2lkdGhzWyA3MjIgNTU2IDIyMiAyNzggNTU2IDUwMCAyNzggNjY3IDU1NiA2NjcgMzMzIDUwMCA1 +NTYgNjY3IDMzMwo1NTYgMjc4IDIyMiA3MjIgNTU2IDI3OCA1NTYgNTU2IDI3OCA1NTYgNTU2IDU1 +NiA1NTYgNzc4IDc3OCAzMzMKNzIyIDMzMyAyNzggNTAwIDYxMSA2MTEgNzIyIDU1NiA1NTYgNTU2 +IDUwMCAxMDE1IDgzMyA3MjIgNTU2IDU1Ngo1NTYgNTU2IDY2NyA2NjcgNjExIDY2NyA1MDAgNTg0 +IDUwMCA4MzMgNjY3IDcyMiA1NTYgOTQ0IDcyMiAyNzgKNTU2IDE5MSAyNzggNDAwIDI3OCA1NTYg +NTU2IDU1NiAzNTVdCi9TdWJ0eXBlL1RydWVUeXBlPj4KZW5kb2JqCjIzIDAgb2JqCjw8L0ZpbHRl +ci9GbGF0ZURlY29kZS9MZW5ndGggNTAyPj5zdHJlYW0KeJxd1E1u2zAQBeC9T6EbmDP8kQME3KSb +LFoUbS8gU1SgRWRBcRa9fd+8qbvo4gV4EWnyo0yfX16/vG7rfTh/P27tZ78Py7rNR/+4fR6tD9f+ +tm4n0WFe2/1v49/2Pu2n88vXaf/1e+8DBvTF+7fpvZ9/aOR/xOe029w/9qn1Y9re+uk5hPq8LPXU +t/m/R/niM67LY6hUT8ihomr1hLJYjdUTRrWaqieMyWqunqCcW6onKOeO1RMy516qJ5Rs9al6whit +TtUTili9Vk9I/KhWPSFx3bl6Qnqy2qsnpG51qZ6QbCHBWVhQ7ZMFVqE32boCq9Cb+RRWoTdzLqxC +b+ZgWIXebNsQWIXeYusKrEKvssIq9EbjC6xCr85WYRV6IxeCVeiN3AasQm8sVmEVeiO3AavQW4wv +sAq9xQbjVTCotpDCqvQWm6uwKr3jZBVWpbeYSGFV945WYVV608UqrOreZhVWpTdxXVjVvRwMq9Ib +7buhsKp7uRCsSm/hQrCqv1/uGValV/kUVnWvnSS+XJ4w2Tbw8QwG20ni/BgAbV2cPYNqB4vzY1A5 +GNboXiPgVTB4agScPYM921lFWKO/X64La6Q38ymskd5ke8YMBrXxHj4unF1Ju9uPqzy0z+Po250/ +ALzgdrHXrf/7jdhvu80akNMfVk8LMQplbmRzdHJlYW0KZW5kb2JqCjEwIDAgb2JqCjw8L0Jhc2VG +b250L1FaUEVYSitBcmlhbCxCb2xkL0ZvbnREZXNjcmlwdG9yIDExIDAgUi9Ub1VuaWNvZGUgMjMg +MCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEvTGFzdENoYXIgNTgvV2lkdGhzWyA2NjcgNjExIDM4 +OSAzMzMgMjc4IDI3OCA3MjIgNTU2IDU1NiA1NTYgNzc4IDcyMiAyNzggNzIyIDY2Nwo3MjIgNzIy +IDc3OCA3MjIgNjY3IDYxMSA2MTEgMjc4IDU1NiAzMzMgNTU2IDU1NiA1NTYgNTU2IDI3OCAzMzMK +ODg5IDU1NiA1MDAgNjExIDk0NCA3MjIgMjc4IDYxMSA1NTYgNTU2IDU1NiA2MTEgODMzIDIzOCA2 +MTEgNTU2Cjg4OSA2MTEgNjExIDYxMSA2NjcgNTU2IDMzMyAyNzggNjExIDc3OCA2MTFdCi9TdWJ0 +eXBlL1RydWVUeXBlPj4KZW5kb2JqCjI0IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5n +dGggMzEyPj5zdHJlYW0KeJxdksFugzAMhu88Rd6AkBLTSpUv7aWHTdO2F4BgKg4NiNLD3n6/TbvD +Dr+lDxL5s5zydDlf8ri68mOZ0pesbhhzv8h9eixJXCfXMRdVcP2Y1idZTbd2LsrTWzt//8zicECG +jd/bm5SfobYv1XYnTb3c5zbJ0uarFEfv+TgMXEju//0KcbvRDc+jAUc13qMCe94SqgCsK7Z4jwrc +sQW4U6zZAqwVI1uAUfHAFuBBMbEFmBTRRAPsFQe2AOF9jIEt3kfViGgSrVHURgQjMitSK4IRmRWp +FUGBTINUg4gtQFLcswW4V4QgmSSpJHVsAXaK8CVzJnUm+JI5kzqTsAUoitAnG4F0hAb6jY3Q6AgN +9BsbAVUX89qA7kiX/dqtS49lkbzai7CN66bHLH+PZp5mveWQ4heSYaHqCmVuZHN0cmVhbQplbmRv +YmoKMTQgMCBvYmoKPDwvQmFzZUZvbnQvRk1ZRExOK0M6XFdpbmRvd3NcRm9udHNcYXJpYWwudHRm +L0ZvbnREZXNjcmlwdG9yIDE1IDAgUi9Ub1VuaWNvZGUgMjQgMCBSL1R5cGUvRm9udAovRmlyc3RD +aGFyIDMyL0xhc3RDaGFyIDExNi9XaWR0aHNbCjI3OCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAz +MzMgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCA2NjcgMCA3MjIgNzIyIDY2 +NyAwIDAgMCAyNzggMCAwIDU1NiA4MzMgMCA3NzgKMCAwIDcyMiAwIDYxMSAwIDAgMCAwIDAgMCAw +IDAgMCAwIDAKMCA1NTYgMCA1MDAgMCA1NTYgMjc4IDAgNTU2IDIyMiAwIDUwMCAyMjIgODMzIDU1 +NiA1NTYKMCAwIDMzMyAwIDI3OF0KL1N1YnR5cGUvVHJ1ZVR5cGU+PgplbmRvYmoKOSAwIG9iago8 +PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0dBVkNCTytBcmlhbC9Gb250QkJveFswIC0y +MTAgOTc5IDcyOV0vRmxhZ3MgNAovQXNjZW50IDcyOQovQ2FwSGVpZ2h0IDcyOQovRGVzY2VudCAt +MjEwCi9JdGFsaWNBbmdsZSAwCi9TdGVtViAxNDYKL01pc3NpbmdXaWR0aCA3NTAKL0ZvbnRGaWxl +MiAxOSAwIFI+PgplbmRvYmoKMTkgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9MZW5ndGgx +IDYzMDI4L0xlbmd0aCAyODM2OT4+c3RyZWFtCnicpL0JfBTl/TD+PM+cuzu7O7vJHtnd7M5mkw3J +AoEkEAKRDLeISBAICRIJcgooBPA+CCqHEQVtS9VaxaviQd0cQDhaqPLTqqXaam21VanF89cotUg9 +yO77fZ7ZWTbV/t++n/9Onuf5zjPPzHN97+eZCcIIITtqRxxqmDGrohKx3+8uhKhx0RUL1xjnry5H +CL+86Or12p4j790FGX9BSLxy6ZplV4x63JtASILytuSyVdctNcpH4L5tLyxfsnDx/05r/A1CX56F +zJHLIcNdFViAkJueFy+/Yv21mfoeg9ORq1YvWmicPzMKodiwKxZeu8Z3p+VZhPI0yNSuXHjFkkz5 +aoh8a1avW2+cf/kXen3N2iVrHu76+FMoryOkVAgHUQGEgPAEKuDjyI9Q+iMIH9M0dXn6Y3qdpgTu +QL2ZgNButAdfjvagI+g5fAruehYdQD3o18iHJqIH0I3oh2gLEtE8yLkdXQyHAPk/xAXpHlSBHoZx +fBgdh7Jz0c3oIPJif/oTtAFt4l6HuzbBSBehcagBrUZ34gvTV6H56D3+VlSDLkRXojW4Pd2Uvit9 +T/ox9Dg6wP063Y9sKIAWwXE8/Znwp/Rf0BC440foPvQevseyF+lQSzuU/Clai+7nWnicXpb+BloQ +RddAG3g0HR3HR0kCnr4EfYT9+EZuAjzl0XQyfQxKhVALWo7uRwfxCDyFRIX56enp48gLdVwLT70P +daF9cPSiX6C3sSKcSj+WPoUK0GA0FfrTg36Lj3Kp/o2pehgxAUapDNXCldXol+hF9BqO4V+R1YIi +VAq6cH36DZSPhqM50Non4M4P8b/IzXBs4F7gJ6fHIweMy910tNH/oL/iAK7AM3AjKSOryYPcWiRD +jcPhWIwuh/G+F57+Lk7gfUQhr3KP8k/z34qFqRNpB8xIHP0E/RT9Ctuhpxpeh2/Bb+K/kQlkAfkJ +eZ/7If8k/3tpIfT6UnQFuhM9jf6F3XgUnokvwcvxjXgLvhvfh4/j1/DHZByZTVaSz7nlXBv3C348 +HLP4dfytwmbhDvHjVFPqWOp3qX+lK9Ob0UzAh43Q+h+hB6FnB9Cr6C043kPvYwHbsAMODUfxHHwD +HDfjO/EjeDd+EvdALa/h9/En+Av8Jf6WIDhEEiRRUgRHjKwl15AfkgfIq3C8Rv5OvuZ8XBGX4EZw +dVwztxpatYXbAcde7q98gH+VT8M4Vwo7hYeE3cLTwnPCKVGRbpGR/Juzj/aX97+bQqmtqZ2prlRP ++q/IA3MYgFGIoDpo/UI4VsB87wSMexa9jhUYuwAux2PxhTAyC/AK3IavhZG8Dd+PH2dt/zk+DKP0 +R/w5tNlOQqzNQ8kIMp7MgONSsoS0kR3kHtJD3iTfcBJn45ychyvnpnAt3BJuPXcdt5NLcr/h3uHe +585wZ+FI81Y+whfxcT7BT+EX8FfxD/If8R8J84VXhA9Eq3iFuFnsFf8hjZTGSg3STKlF2i7tk96Q +WwE7n0d70X6U88MnuI3cJG4vuotU8QXkt+S3gM8L0GJuOgFMJbvxVnIT7iHFwrXiGDIGX4RO8XEY +6xfIQ+QMGcNNx9PwLLSCDDeeJubzT0FSxz+P+vjD0LffwpOvFRV8M/lcVFAXRqQW6vwfbhif4F5B +b3PvYYl/GP2Zt2If7iNPcA2ABb/gxwpNKMo9gH7OteGb0F4yCSHrt/I2wOOL8FPAF2bjSvwVl0Yc +uQiwqIb7G7oVrSR/Qn1Ax1vRj/Fifhm6C1XhG9FH6GdAFWXClWK56MEvkcv5DpKHexDhn4Te1eJi +zAn56Dbcwt0vfk7eQlehV3krepd7Blr/Kvk5N50/JVyMlwMF3IQ2o7b0RnSd0MT/Hi9DHG5EJfwJ +4G43cpV8FNINwFXmA0/bB9R9EPjAOG465PgBcy4EvJgDHOJ+OO4FPsEDBl0OND4XuNhvUY84m/Si +ZYIDA9dBiH8ldTGal/4Zui+9DF2ZvgcNAX6wJX0jPHE3+gBtR7vxptQNaA0KA+W8iy8UJpNXhcnp +IaSDvEVmkZ0D5xdGuwT70adw/BxOxgqHUAf/RzQL1ae3pf8A2D0IOOx96DJ0AToJvfwMajifO4qq +UheRzvRkbg309z00M/1EOoKtaHl6FZqBDqPHJQEtlBIwx0n8e+jvDWgJuTi9nluSuhzGYTuMgg6j +dRXwn9v5Nv5W/mu0DWh+J/CbXUA3TwHlUNpH+iWb1q9b27Zm9ZVXrFq54vLly5YuuaylaW7jnNkz +Lhqn1489r27M6NpRNSOqqyqHD6sYOmRworxsUGm8pDhWFNUi4cJQMFDg93k9+Xlul+p02BWb1SJL +osBzBKPBk2KTW7VkvDXJx2Pnnz+EnscWQsbCnIzWpAZZkweWSWqtrJg2sKQOJZf+W0ndKKlnS2JV +q0N1QwZrk2Ja8vjEmNaL581sAvjOibFmLdnH4OkM3sFgO8DRKNygTfIvn6glcas2KTn56uUdk1on +wuM6bdYJsQlLrEMGo06rDUAbQElfbE0n9o3FDCC+SaM7CZLt0KhkIDZxUrIgNpG2IMmVTFq4ONkw +s2nSxGA02jxkcBJPWBS7LIli45POBCuCJrBqkuKEpMSq0S6nvUF3aJ2Dj3Zs61XRZa0JZXFs8cL5 +TUluYTOtw5WAeicmfdef9J87hYe7JzRtyb0a5Dom+S/X6GlHxxYtuWtmU+7VKI2bm+EZcC8pmdza +MRmq3gaDOG2WBrWRTc1NSbwJqtRoT2ivjP4tiU2iOa0rtKQlNj62vGNFK0xNoCOJLr4u2hUI6AfS +J1BgktYxuykWTdYHY80LJ4Y681HHxdd1F+hawcArQwZ3qi5jYDsdzgyg2HOBJdlrDGLFKTTt4uzI +Ytqi2FRAiKS2SIOWNMWgT6NotGQU6lg0CorBrxnDXcnFMCOXJy0TWjvU0TSf3p8UStSY1vElAgyI +9f19YM7CTI5Yon6JKEjxJItqcN2Ek4lEsrycoog0AeYU2jiWnY8YMvjqXhKLrVE1SGD4UAOM7cLm +0RUw/NEoneA7enV0GZwk22c2GecauizYhfSKRHOStNIrR80rnjn0Srt5JXt7awwwuQdRFdmTlOPZ +P6fqzZu0fHQSe/8/Li8xrk+bFZs2c16TNqmjNTO202YPODOuj8pey0DJvAlNXJBkIBLk2FVAyvnZ +wvSkSUnyJfAnMqRe3CvJgJUsB2uTk2rr+UbcbI1G/8ubetOn6F0sOXdbppnJ0YmB52MGnA9ontLB +QYNBvE6bPa+jwzrgGqCaUeHUTAIYj2Y3RbUJSTQHKLME/nrTR0fR0BxM6jBkE2gBwD8jK3M6oGAw +AzfDj2LnkMGTgdF1dEyOaZM7WjsW9qbbL4tpaqzjAHmOPNexZlKriTi96YN3BJOTtzXDWC3Ho4cM +jtErHR2LOxFXAtXowU7MgJoJdzQnZySaY8nLErForGkJ9KVzNFKis1snAETQ+M4Y3jqzU8dbZ81r +OqCCVbJ1dlMXwWRC6/jmzmK41nQAjBmd5RKaSzPpiUZP0DQMQ9NFZFY+eADsmHZ2lWcZ7HxRL0Ys +TzbzMFrUS4w81agozirSQbFc1MsbV3SzNA95spHXbpQelCktwxWVXjmIQOIgdtH4dcLJ7CbdWqOP +1sfoY0k9gRGhWV2QcxDKjsGoeyyux8FOeObFLLsXt3eO0YMH2JMuzpRsh5I0rz2bBy2nxXIeBPUZ +HZ9zrgdz5jV1j0XwfBZDifH0RzktNCKXhhhjong+N9GkkI5pswAD6UXrqKA157JGb0ziWHJB7Noo +7V2yMXZdFDJjSQ24NRTqRFNCzR0dGhwxGJVFjU1GTC/hwSF4UnOy/TKzbDAEOHHuVIFbGV51hygP +ydZ2g1nbWqiNAh1mdclF31sbtD6JL6Ex+2PN7xyJYkb9IKWNSjvmd8wDfIwmC2nFmXbAqSPUzJ4A +LbmXtQQz4bQIdIKllJY0yuSATcYu6CQXJViKWdpxQWzSYihBAwjdETBZUW1xMy0Vo0RDEf8/FsI5 +haggYQ/vUMeYZzhzZpBvR3LZwNPl2dPJNICOUjLUYBPQF0ay0eSKYHJVcyJbZCHtcwfQ9mhK4KPZ +zVNoaAWxMyXZvmghNBHkzdRFMci4ADK0psuMEaSCuoNqTosWwm10lDM1Ja9MDHgk8AQMLAoeRLuT +bG/QWpu1VuAheCYMdlBLCpBqS0F9ii2kfKPB6E8DMH9IFnbMgnsRnbZgUgJ+tnThkhhlrkmK78bo +0zby0Do0qymJgh0dMcAhaGLJZCgMj48nxfhUmsDfmkRs4RKq2S2lit0SQ+WA5rLRoU8LTopFm6EI +KWFjCQMHhHYZjRZ1UL2xpTUBI+HqcHdotR1A8C3Aq/j4osZW4Guaqk3W2FQvDMIZDMJUetYMDzIK +WkpoQbif/cWTVyQ6W6SScznsb3XCKCyzpzIlItlgFpHYHwBtiSTxjYKLtPP44nlMLsBE0cETSqbC +8OqAVUF6N1DR7IzYMO6fSm8NmhNm3AY5zaYAAHzvLMFbG3I54fyke9rFlwRhYIdQyS2NTV2EJqjo +m2e/uR7aigfaGug2muP6MdkL1vLLSIKnqMwWQIIvnUYCIp2zN42zcYPpQYpQIYqAmV4OhSNceZdY +GOnlBnXH/ZHXDnNl6AQEwpV1JQojB7hSrrBrTETv5WLdbk+lc9wQToOqKlisQbwawrMQjkDg0QIu +DPkqxBsgtEN4FsIRCK9BEBGCmF7VIKyG8BCEE/QKV8iFurSIOq6UK4B7C6ADTs6HPoeQhsBBO31Q +qw/NgLAAwnYID0EQWTmasxrCBghHIJxiV3TO13VPFbTd13UHS7pXrKpkpwuN0/kt7LR7brORTp9p +pBOnGsVGG8WGVxvZQ8cbaelgI3WXVLbT1GqvPDrOy3mhk15o+BqIMTmGnBiDDbqL86AkBMKJmRyd +c3cXxysfOsLxCHOEw2gxiqSPcrjL7qocZyVp8jlyowj5jPQZV0hft8NV+dC4C8j76FkIRyBw5H04 +/kr+ijaQE3TMIa6H8BCEIxBehfA5BJGcgOM9ON4l7yIneQdVQKiHsADCQxCOQPgcgkTegVglf6Go +xGIK10Mg5C8Qq+TP0K0/Q+wkbwP0NnkbmvZ6V01t5QEGJCoyQKQkA/iCGcDtrewlv+/6ugwwKg4z +DRh1iCtCY1EVV9RVMhzQz99Vd3mkl/ytW0tEdo0bRt5ASQgEWvIG1PwG0iA0QGiFsAaCCNCbAL2J +2iHsgLALQhICYBnEKgSNvAzhNxDeRMMg6BAaIMjktS6oppe82hUfHxnnJb8lLyIfjPhx8muW/oa8 +wNJXyP+w9CVIw5C+TF7oCkfQOBtcR3CPCqkKaQVcF8ivuovdkfQ4FzkCYxeBuAJCPYQZEBZA2A5B +JEdIUdfiiBsecgi9LCMo2YU+YenP0CMy0ldE9PgEQECNRvHR5wEE0UPaQ3Gix3feB6c0it91D0A0 +it+2DSAaxa/fCBCN4quuBohG8cUrAKJRfN4CgGgUnzEbIIh6yYP7i0sjNTNWYm2ck1wDo3QNjNI1 +MErXIJ5cQw/0NU/b9pOu8nIYsfv1RFl5pB30o8O4/WLc/ghuX4Lbb8btG3F7HW6/FLcncHsIt4dx +u47bD+FRMBTtWO8ZcFqr+3H7y7h9D25fh9vjuL0Etxfjdg3X6L0k2jW1iiWTWNI9jhIdpOeNBe7j +JFEY0SjgfBR4whGIX4WQZmc6FNKKjMIFYZoWdZfXG+dDR1euBvJ5Hm58HqbhefQeBB4m6HlAo+fh +Ic/DA5wQ10NYAOEohM8hpCGIULoIGr6dxU6IKyDUQ1gAYQOEzyGIrDmfQyBodaaJz7KG0UZXZBo+ +AwJPnoeDelCjJKoXqiE1oZ7PbQ9hZxjPCKfDpAZ5vcDT3S7Z1Yvt+/5l/+pfdmQZZyF3ke2UdZMd +mXR719fAuvG9XfFDkXEe/GMU5gHzcC2K4xJIR6F17HwECsk0rUYh8jSklV2hRrjN2RUfHDmIHfSu +fZGvQycjn4R6CYAfhw5F/qj18rgr8gfIeXpf5I3Q7ZGXKnplyDkc78WQHNRY0QOhUZE9L7OiG+HC +/V2Rm2myL3JTaEpkZYhdWGJcuHQdnOnOyMXxeZHz4XkTQ5dF9HXwzH2R+tClkTqj1Ah6z77IMGhC +wgDLobFlIVZpLAw5PZERc+bU9OLl+mBpp9QkzZBGSpXSYCkqRaRCKSjly25ZlR2yIltlWRZlXiYy +kvN70yf0BBWc+SKTnyJPY57BKqExQUyuEiwTdAFK5nHTyLRZ4/G05NFFaNplWvLMrFgvtoLxKMTG +Y5DOaNrs8clRiWm9UvriZE1iWlJquKSpE+O7miE3SbaC+TO7qRenadamIHXTHEAYuzbdGaTpoE13 +Njcjv/fqen+9e6yrdvLE74laM3Hi3M8/AC4cn9w5bVZT14innioc35ysZHA6DfC05A+oO+cA/gKf +mjTxAP4HTZqbDnBj8ReTLqb53NiJzc3TenEjK4c0/A8oB6jzD1ZOBilNyyFNDhvl7jfKlcD9UK6Y +JlDOYkElrFyJxcLK8ZiW61xXPGliZ3ExK+PT0DpWZp1Pyy3zcgmUKSlhZbzt6GVW5mVvOy2THMuK +hEJQJBxiRXAAhViREA6wIo3nilRkityeLXI7q4nD58qEjDL2E2YZ+wkok/hvf0vGJxK4e0zzovnU +FdYam7QEQmvyjquX+6lWr3Uuas74yOKtly1aTlPQa5tjSyYmF8Umap1j5n/P5fn08pjYxE40f9Ls +ps75+pKJXWP0MZNiCyc2d09pqK4ZUNft2bqqG77nYQ30YdW0rik133O5hl6eQuuqoXXV0Lqm6FNY +XYihekNTp4zGN0+Yb6TdxGYFtG0FW2C8V10zluHwmKj/5uBBUF12I1uiOanExiftEOilIeOGjKOX +gLToJQf1d2Yu+W8eEw0exLszl1TIdsXGo8T6q9ZdhfyTLp9o/K2DH2Stv4oOuBEn1v2nH1yblNQX +TqSrq9OS5bOmJevBgO6UJMhtpV1KjjbzbLZJvemjRuZQyBxNMzkuW5Dm1dE8iyVT8Lvzf1UmnUCp +oJ0c6sZ6GK9H65q5ZHjabAIcYXbGsXQQFCsqK9Y1QwfX4QReZz4j0+xEAhnniPbZDOuvykCZsVif +SY074ZZ15pBkf3SwEtkRW88ey4YzMb9pnIMbyVWgcaA7D4N0CKRDIK2EtJKr0N3xCEdqIha5JmKz +ToxI4sSI+dTmBGKOFTAcBNDZwZ4Y30PwSVHqJffpeUjgT3LIKvEnMSqQReEk4Q6T4ciC78NDkT+h +nqnrr7tIPV03vb8O1QOsnoVo+LCoK+oqgQiYLjqrcUfP6gL6Fmn8UagLXcp1k2uEg1CdDf0guSkB +I4zSX3UXlVQLvemv9KJ4WbVNtEoCAoEmCKLtM4sscxxBklxndVraLcQCs6Z77M5qy7uY4+sI1u2u +alygtD3hT0BjErQ1an+ipY41SoWjvw4i7HLX1tIwfBhOJIK6gnnJigQRRAaIA399vXrMVztseHMe +N6LKw1WxeEfl8SHvDD8+jOvGvlOnUp8YMZUd8yCrlPWijvZB9yCBw8JnBHEbNbwDE7xCpO1Rz7T0 +ofo+bNQb3At90lltgeO15yrbOpRV4f7yy9Rn8OwbUzNJq/A62HUXsWdbS50guNySrKq9uKobPeSQ +IdVd0kOOSxGnchrHcc+4frqNVdd/pk89A3XW1cNE4JZgN3JKmHYPasNx4qquGVlTJUpweFSM3/vR +b6fPO7zxutLzYgmcSM08jL/Cjs/e7v/2teaOnYd+kYqkNDSgRVezFimDyCCVWKwqRm4LbZP1IQ5D +2gOG2qWO3vSpHlUlcwD4qsfpZMDJHrudAX/XnVYrmeN0RBzE8Yw702qKit9pOXZazJbnxZCrujQO +R5XX5/WopH8jTGLReaXXbzw8b/qrqZn4BP7r4QM7O+b9/tv+tz9LfZGSabvXoj5+NL8PMK2ZtTuC +rrSQr2XuSkESLVdaeevXAr6ynswghBQoc+cx/GmZfrqur049WVeHKk4D6pyGedtPycMqcaSXq+pc +xSF/RaKqsrKqogKaVuKKjoi6qlxRT9RFcKoNb38Kb0+19eF7dtN0d+pK2pKnUu/iW9FxZEWLaUv2 +WoHUnhZ7cYMex1wdIdiK65AVLESuDomjpNEz0AK0Gm1Au6DmXbaH74VROt1y+qQKLQOsprHap/Yz +xKJ4JYmY+kopXlUch0ZVAVrli1LpyJE1+443zK2sHckdP952R3x6wcJLoDXjcC9ZQa4Aej+PjUvB +GrKGI9PxdGhIDJGAsAYKFfBr7qQjcrJF/RBVTO8bPgy1wbR0IR1mpSJAq8kbEfWMI2W4d+9euOEg +dHQL9JFDNeypfkK7VGd05FnE74Iyu3jWlzMtjC6g6d3ZhmeaffD48eNMO0t/RGoB5zhjxA4gLv1u +V34t6U2/q2v5tT/mMOEe4p4Fq/pqhPPhDmBjwKu4jxH5GHDxyb0I8d3XQ1116uk+1cCrLcLQRMtN +6jGKX8ADuoGTmRjmwVUYP7kj1VQg/P2bfGAJc9If8S7hKOB8IU7RFnQSw+EcCPNCfthu9wEj+pjh +NwX0AorgFhdSaA7yKgrECs1DFYDcxyE6Dj1mfe4Uv/uk0/AkkT7pQ6AUBnymF9hsIn2kSnOQqig0 +pnnZR557pn4RL24hW21bnS85BItk85NJeRd6LiiYEJydN98zv+Di4EpppW1R3irPyoLW4HXkGvFq +2/XOLeK90k71Jf/b5E3xTdufnYFsk8ap6dNIQQpMTyPypb8AGrJl4K+QHdmxrrsafessejRWPQzo +1KICZx5nhZvMgpb0x0bB/Y2WHRGXoii9YB42uhw2mwHIdjsA3Y2udYiydAWepCHqFjOLIjlTFBlF +9zWiHeEX76D4A11vSfRBTMGWNgZmhgK3tKGWJJmQ1BuaekStQA0BQ+oimu2X6RPIC8ENwQlhFP1h +CM3NzcFOe34vV9Gzym7nAwB0reIFwIxEfYKiueoeWVXp9bqB8YixotJ4nuqtqhzpUuOxIkmcs/L1 +XVd3rR+/4vWH37ju7gNP3njjk0/efOMFLeR1zOPznlnQnUq/nUqlnt9z737809SPPz+Fl+MVn12+ +GXD8PRCI3wKOWbGDYli3NdtzE7Cao4VMwGqMRXZQ9GgjRyXgSn4D2U7uk/lneGxBokA4i4AVgl+2 +stG10nlCmDrzwD5i/BmAT3UXQ9cQQ1cHQ1cYLb2AIqOJcQz7Aoqgg8wV6LMc9FkC1gRdIEKB7SCu +w5uQwSrajBlhPzgxNIN6Xy12UbnbglpAzLAfCGCCLaIuCBasWOhY17trgasAQ4MRj8ZcoiiNAPZV +Rb7tGff67B+/X7Gev2HsjZGfT3l5AfShDqhbgpELk1JGmwZFWVyq3Z+XJ86xU4JyuRjwmW5RVYDC ++UKYEqqPFgiH6dVwyAFXwgrtYbiXHII2WX0+LaK6CNEi0JSKN2iDKo6jCopgiXoaH6ukJEyyFSpu +N2EV6hani5j1nNBt7jwyJ5xP8+izu+DRlGHYbGSOj8pBNtrfVxulalofrY1Vpk8ZI4wRDwlHxEPS +i/JLIWmq0qzMdqxUFjuud1+fd7v7sPuDwAfBUwHliG1/HglbVVkUXw4F8kOhgBwKAKeUAyHOHlZ7 +yWPdM1zY1Yv9e2k7EW1YNyaKdQC5W3PI3Zold3ujdZ3vdWC0lOTxIbIRaUjFo3TFtbeeLCCryQbC +k4OkGEXw9k5GpC3AeM8kKP9l1AnCtL6vv+Wky03xAaItjqEJB7BjQ4plSFa3BNWQWqiGVfGX6VNI +AkKVIbVAMOl1VDNqwS1rgWrp1NqDkmQnYRDNPauIkm9n1JufoV5XrasKhpTKaU80XgMINXLkiGqg +WyYcgahBTIIuJEq8dLaG+Eoevf/z3ffdcMsD+EDeV797/cz5Tzz3yPzwnj3j6hYdvfnYB0tX/uCB +jrxX3/p0T9NThx/bunA4YGJj+kPeC5iYwGdypIStwK/T+fWHEKYkk1DgBJfFrHan4gxbrWWecIgP +l4WEMnvMrvgLQJHSVEqEmhSnWEKLxysojweBDgdy14KGCnIMOtP3gvqCu1Y9lqikgeLHMMHutU+y +b7bzk1xzXVcHuYu9q9QV+Yu9V9mvy99s78i/Pfi43WpT7A5ewlAfpohAF2kPYbpN0o5H9CiKh/cf +JI+hArJct0DrBGie3T0AL9w5eOHOEQPudQu01RrR/JSOtHZpwE1Szk1Szk3SujiTHXGM4mqcQK9P +76f3x3cM8ffiUV0Fr+ODeBSoAUd1W1Yy7Bjci+/JIFeij6FXhvmfTrRkZUD/SUpGoB9RXDNQLYte +XYLGAXUCGjVTdoTbKBIhjPmYYndaAXf2rnI6Q2U8QPtXldkL/P6Qh2FUiGFUZUUVRSqq/9VCUkWl +Q42XSgOGVVJNFjQRjGKYRGMUK4o39kR+tHLDs4/cVHVhvtu2rnfzisu35fdEP/35tS+vXLr4lh2p +j9/8VRrf6r9vS/KWGx/Of5Bce9OiW267Tdv74rKuxQseGBr+xV1HU19+SO2oAHBAFSwQK7KTEMW8 +w0hJf2MMe0+jXcwIEMGUJKIJWLKyxQQEU7aIJmDJShsTkORMYdkEJFM6y3K2TEY0ySYgmIBoAhYT +yMgxvabR3aQsV+5XnlReUoQLuQvtP+Q5N7AspIicJFhtnATS0G5/mePzOY7n7Igodl7iDpFDoDgS +vEu3Ip6HIuhlK99Llu4XBKteGKm2mmLOauhUDPiMKVfWXlyj2yW9KFYttUdHSDuchNKozZ5fjYhK +NAKKPtxM7wHg5D56D9nr6MXbGOr9neoeVMqdpjKhTv1QZUIO7OAzda7aWmbsbRma4IGzOZ1OEHvM +jWAH9dVdC3LiDd1WVcsVDanl+MLCOmaEAyJCGT1f0W21SntDraLHa5WiEKRDag0zHX+PlwolgvsU +3iJydrBLKvdT1QUpvClKE1VVlYYsBQMFV7mqPDEX58JkZ/9t5Kc/eOGFntQIvOBxbt/ZCx5PPQyc ++0f9K4EhUK03KvwM5KrENJI8E0fcJpCnZGbbbQJ5SmZK3QAcoIRuMMEDCMOo2ukw4pDDGvZ4Qm4q +ZG1Ong+H7A6MJD+oIEyFZgBjmFT8UYZHCRm60X8MmBzlcdVuJqadLJ4WuK6wo3Bn3hN5zytvKn8O +ypY8v6M8wOVZPe68vJcdznxHXr7DaQc+p+fRqnXHLrA3HU7dgzPN2O/k8euUB4Iw1F20Qa4F6mp1 +g7pd5dX/mof5GQ/zgxWh+onf5GH+HZr7MB6BnPhHUHJUl2Pv9/GyyEBeNoCbtVArD/gXG4MW4DQt +wPxPbpGHJgRAK5QrMHssw4RhtoMgJznG1yhna2uhrh1T0UIoZM9zgL7BewwO5/E4QzxTd0N2pxsk +Z9cqJ28KzAoaAF9chtzMZW/A0/LAzuWAryFPvgS6cHzOLzz3rbqlZ8+2udsGPXkXeat//4zb7j6K +5fV3nv51P25XO+449sj9XTPqveQfz6Sunp8687sX7+46Ad2fDpjmAblZiMrxJzmSM+LEEbwAczg4 +KKzbsd0O6lRQKArn261hjEpUqmgxW0sN+1SKOj4mN33M1vJlDKPjbxxX/8dEoZY+9VgLRaEhKwvw +REn3TCyYqM1zz9ZWcoulxfIK92JtvXxVaJO8OfSm/IbXJWl0DksNFiDOiVFlLkihKLtAm9VgJ9Cw +IH6d6qK9VGKajcRUdqG9JQPwpyQHf0py8KdkncrwR8VIBVYFfTu1n+rc6o7BwKNGdYdNogubbDgM +XPMQe04Y1+r2et8C32rfBh/vUzMFYDQYW3U0+rz0UT4vbbOvlxR3J7KmkyErc/GtzxCcTGDCgGWR +6wBVwHpKtZgW7TWxiz6Ays7m4F6MBat9EMMpuz2YX8RwKt8eFJjIDArncKrSwCYsxUuZ1SRKVDq6 +qfoVK0IutYbKSpyfg2vct93+wVNXNo6bcxkZd3hZT/81r93219TJn97+8Z53+mtm3HXR2sceueH6 +p/hZjhXDpg8b+9lfFrWm/vX7jr6b8TR8I37yV7ufO/tOy1PNvQ/e++yzMEsLQV56hSdg7O9g3gnH +MTvm4Y/IvAWECmVMwwjmLYp9HccROi0zmFbLkYBTXmf5XzQDsHIB4eohWY03gG1X4MgQMPUatdVN +P913kXqG2jzU20C1XdAQDNUW6DHYY1E4wBVKa5jRWlV9xoMiIk6UYiPd7pqF3N5tqb5pI50HuFv+ +eTv/zZ5tP0q5U9/2/nkP/hS/+ADi0CygmgKgGh+KoWHkhXN006OgYHgoFWNg35A5Q4e6o2FRGBR2 +28NU4DMnxel9zEeRcFIPHSUdp2mQUIBddPo5033HmaW4LMlxxR6FFvewJ3oYyXnO+SIGOjqoDOpj +bk/DOtvPGiKaDRGNhpxkfg+nKWYz9dM8AM7qRTSTVkvv9DDe72E9Pdc/szKoC1dkGmAGSvXTR3hx +mXeqd2r8Q+WTYYJlGL4J3YRv5NfLbba1ylX26313oA68jd8sb7Tdpmy23+n7jeuFPLeCwn6kQE27 +huKcwRxA1+Ecug6bdL2vMbzuiAVbxrnJMpTIKZ3IKZ3I4QKJdU5dAy7gxMipOomzF9/dU+k3Sd9v +kr7fdIL41yU5zPWSZd3FZqFis1Cx6VQpXucxTXXNo3uIZ8fwF01ZwwQMc56czsqbrPLsrm1hQ2m4 +rLNsoCh9oiukBYAJdGlaBU2GaKCzn+gs0xhXMOROy9o21AZ2WTeM3FDGFoJB0T2IsQW3XYwytiDm +sAXmBcfx+IjqjDFmqsoIcvLyc7hBLmvAK9as+vDI0U9XXrHlztSZt95Knbn7ss0rl2+6femyraOn +7pi1cfeeWzY8wQXL7l2x6+33di39cdngY1sPp0HNP7r9V3j28ttuXbBoy21n09N3zPhZ+y1P7UYZ +fx+lrDAqJ/PO+RT22yIg3UtcINvPMLSkQp7JBT91lAyieOl3McR0MX+Jy+8anLANClMP9wwH53Dk +owaMmRFoV13iHExVjSJqfNPRPpZoqWQct5INOOAsJSKVyq93/ifrZ8hpxDl1SS9n+pKL0eJ/qHVg +Xf9WVUVuRfqU0YELvXrsEu/c2FJulfeKwLLY9YGbwtsCd4Tv9z4ZOBz41PuhdkbLO8/7oHePlxtd +tlgkg8IzHAuoXhWileDXGwxp2EOrjYwrzcH9SA7uR0zcpzCuRbaccrb0mWw5W045Gx6luwYqWzsG +U1m7F2StSQUlJhWUmFRQss6VpQKX7iKuHYkBVAAiMEMBGfzPqlznROAhVAq6VSx9ojuqiZrpf2jD +Lc1MAPI2hyEAYcyzShWThLleiKwANNSpsWREdSmVfJAiQHy3i3kW45iht4fh/Zo93hsXzrqpYSQe +eeiKfWex9ML2vhuu/8cjz7xNXnl8/bVdT95408N4lnr9lRdu+NMaxd+4Est/eg+r96f+lvoi9VGq +++dHuOqf7Dv2wDYQf4DfBxDCm/k4W+Mz1pU0sBVEyULEOp6rwyJvJXWgdiNCfYQPy5k1hzYqy/pU +Ywkrs4ol8LK5CFBvLANUeehC1oHjx49zzcePn33i+HGoka15sBod6CFWY8U62622H9getZ2yCTCl +cWuNdbK10brEutf6vlWyWR0SbYlUJ4qCg7c9baXrIzGhjmeN24iQIEp1vHWUbbRQwdfzROMx/7DT +bGjd6ZNgiNGFEWqM9ff3qcYqCWs6Ul+iYhitbQvut1kHdKAitwvZRZPjmWUTsz/m4gnd85OaKf1B ++AOagubiEaxfc/moqnmj0ZIR9irHJMdU/8To5OLJU6c0znZcX+bwlpThuKW8MF42IjCydkJJo7+5 +8JJoY1nj1ObGJf4lJUvLrg5cX7i2eJP/tsC2wjuiW+IFDrXBgbhZVCmxOkuH2RpsxCZ5D5Hz0QQ0 +jRzqmTCas0aoETMaa4k1CZI4iKejUnJoX8X5xU4JS73kVt2pNoxFxe5dzuJh6hpQLg/iJ1GQPNhT +P6q8GMpbUIw8qFu0EXhEQdPcbZm1r75+aom09J3uh8Fs6UMVfX0twDtOwjDWt5wEyshoNNQBF9SD +5eUVo52lFU6Hc9Ysm807ehonI693ghwZTddVqurBjKhnhkSVu7ayvqoiY1OUUNSnTJ/51X01VZyB +8zUj3SOqSXGsiCeefDdfpRXXVIkiHysqLi6F0jVuFK3k6fofMz1K4zg/Q0tANQ7C3z7u4ZnNuy9/ +9Iu1cx+sLereES4rHNG4dtPTqT3HP03d9Ic/4B98iUV8WdPeqq9ST/3j3dTtqa8mzF58Pf4V1r/C +d6xd+Jt9f5o0J9+e8t4ye9SNbedvWai3rdAfnXbJ8j9tfAjX77qk5Sf9C7c5g6XnNWD79idw0c// +nFr26ZepB59M3nz52xvWfvCjX/z59DvYibVXXtrzSurdv75cXlqAL7z93gm3vbJ0685xO34L2JPu +BzRuFg4CFTpIB8WecYVgJ3+V43w9m4UtOflCDsybcI47RuSzfhlF+WXmlm8MZgrFRJvtl5l7T5uZ +RDEz8blM0Wp6c7zm0oNp6NtMp5LVanqOTMDiMJth5khGzv5G7HCqzJHyRU8G+IrJT0LVymamETLt +TmBxhTpMXSYvt7SqW7kd6kvCC+JR9ZRqk4Vm3Ega1OW2pPpP5Z/2fzosvMLbeQdns1oEnlfsDlmU +JAVgWVQkjBDdTOBkyxqapOTDJcJxNM9D8ziNV/LhLktYEOSwyIm9ZI1uQbLyiU4wIQexDXQFm+5W +NLRE4i5u4F/l3+O5HcBvejHWbQ3KUek9hduhYIWeq07pVYlskNolIv3A+eYfDX5UAAH+/EA6gQK1 +rw8Ioi4ApFRHF3H76FJkAkz5LUP9LDW2J9TWblGPHXMcO7ZFMFJgWtOStlnTkuGZ8wx5NK+ph3dy +snQwfYpunDD0rrVtLd/jIMr+gp2y2MsN15VVsowwMD9ZwYQRaD1bcACSjOEqHOOiXF6Ui5eKEkeq +fkea3nm6/ycPv4X/cd/kolCVcPCbyfhwaiKZh3ceuObOO4Cv7wSb6hPAZRez4t811mkBwfQyukrJ +85NjjbGlsXWW2yzi5YGrhDUW4P/CrTax1Gvh/KXlYW+hBfTpj3Pw/ePvLh/q/kaLJc8dLi8vK0Oh +wjBMUCQcdiHZD/emsvf6czQMP2gRCrvX2uiPiwo1Z8Te9Id6CVWeRDdVnESRIoIo05aKDPXEfIqW +4uySAc8daLubz1UbS+JKiD5XsdKnKRSZFfosJTAY2vgdu91qmuVhjS3CaZkVuDNMn2NAZvXtmx6G +tQYgGutxVrYG15IYM9+fXV9rqeun7seL2Pl0wwdu/M4tt0CA+a0DuUhVS7oa4q7FzB3O1uKCXRZ3 +OZike1e53RgZSyhIxoWGlUpy1HS6OO+K5nizHSSGo5XGako8FoVrNYwRA7yTxHe/sm7psk3b57b/ +alvqB/i8jaMumDb5lgdTf8ZXXBqfMG/07B9tS+0RDjYfWHLpz6pKD7cv62wdzl3s8i6dPnV12be7 +JGXUyskXX0dXV5amPxKuFl5HhbiC7ZtYRFYUEmyYrWxsPtYXUEhDlfZFaA1aX9iObivcge4XnuYe +tx/geuwv2l9DJwv/WehyuAtdhYVcuTjIVR7SIlPsjflzPY0Fy4WVhTe473Dfz93nuD+0Gz9Gdrv+ +4MhD+Sig5qsBnm446BpUyxR4bVCt6gQCCuaFFS4Y5i1q3HkBimugaQciPnPSfeak+zKTbm30xTUZ +A19mp/ZGmWGKXBBeNN/Ys5RoYRMIcwlAxhnj8hlblVroenYigdcGdSvwNd6pqgof7OUqe1bxFiUP +gK5VCmfMFZW0mWUJ7GOCE+bEXVwFUlOKU9WSylWqXPI9z52Xev6DvtQff/IsnvDcX/DgMUeqnvvB +k3+bf8WHmx99n5Dhn3/7K3zl7z/AczpPvDJk1z2PpD6/+1Dqk47DVAN6EGTYPKB7J8yLoUu6tQie +IBvU6VLDTiT7BlDRwB0EJhVF6MBYcIQtlVkYSVisbEeFn+UwomISIhApVM1hVa0Zf7NqKP5AVOp/ +TVT/MonqK5Oowt9DVJnTlgGUNHzYhOv0kVxQkkVZkHmZFwv8AT8RbVbgAVZQYbz53jwvJwY5XxS7 +HRD55VAUe62uKErQde9y+G0EvakTqd9Pahkq83l9XrcnnwCNlUQrM0uWpUBZD+Kvn553c/P6dRdd +f/fxTalOXHv348MnTf/xqov2pH4jHPQUXnhZ6tVjT6RSTy6s3DNy+KRPfvbhv8rDdDfNI4A49Osy +NtRn7FcThbAsSxLieDplVkvYhmSJ4ni+6q6WZnMXaFbNTqwBO28hWRlvrg5lmZnl/4GZWSz/gasp +Yy7JUEFmCqabjK1l+umT3+Fk1CoWZMa1BAEjizmU/He4ljGcnmgmPMIXn32QS5z9A3ebcHBPqv6Z +lH0PHRsw//lNMDYW9DobmyI2NttBjTaHB4bmAY1oNkICtv+f46HbjJ1BGfaV+s5oWMfM/4+jcdLw +K1L7dMBI7Gcj8W9D4P73EdjNvXP2A5Lsb6C9H72nfym09ArgrweAv5bgJ1jfA8H8oIe0luJL5Tzs +5oqLUdTtIyUoTBgD9NDWYiz6wg4uGhYtGMdLS4oHUHpxDqUXZynd3liscRyMYWkrW107yUaGKYWZ +Zba3GaYwpdBBayFr20txaaE52IXmYBdmmWphXLNia5apWpn7xVoQX3TJAKY6XW05kxlJlQ0lVXmy +HkoYTjg3lolrqWUDND6RjwVDgVBBiBOVuFriiUficgkfj5X47YVR5HXmRaFwfp4mwVmRUBLFIRsQ +e74LorAlGkXFHERs2y8QPbVCs4oYJX/UEtzP6cXFUQdzB+9dhbGDesYq968SLe68PIePsXQHN2C9 +2cV2x1C+PqLENYCze33SUAKsnW7ppEYTMAwXdyG5YnvqtV1/Sj3U040b/vwQxvfEn41etm/1pueu +iY7agsndN58aS+qfwf0n1q47gC/905t4Xc+y3h8OW9M+feZtM7Y+dCz1VfvCGuwCHHkMuH0R5R14 +sqHh2QETvHmeap4LW6y7rK9ZiVUgxCYDVxyACnIOKsgmKuxtlDVJEulaLFPGAAV0G1PI2DqOSFdb +PEwpw0wpa2m3YzuxmXhgM/HAZuDB/kabltnVdFS3QqP+C+KTM8SXIwu8GVak2bFmb7C32tfY+THN +/kRLW3Y7U1Y2GOiUqDOwiW0srG2pYAICg6rNWWFWdfsqjkMY1G1ZIIwg68/p2nRxjW4ZjUH82HPk +m+ee6xeFg/0/I/O+mUy6+6dDb44AY9oIY87hBrYOS8z+cyZApMxAcACMs2fMuK+zA45MGIoKiiEw +OQCyRb815oMVzcD7GimvI3STV/eo89hmr+6qaiMdMsxIB5UZaazESAvDRuoPGJvDyu1qtSbsEJ4V +gN5BX9mOdqEk4iuQjhrQe+gUEtwaZO5AnGAsutO58Wfm7O/mnH1mztkZXTWMODZnj/BvNucI6wnz +m7rawVJraW5bW9efNYHoajxTnbL2TzcwR5LZ6UlH/8hz1JqBcQYLRriY4jaZzfhfmCuqqZUto0ut +I8SR1inWudxm7o+cdLX1Le4tEPGUOzHVZJCwje8QnuI/lQUrj0fwb/J0X/oJ3eKOVnMajUBt7FZq +3TS3G87lTMrTtJClR7vdXpr/rj6hAOosKTlPthQUnMeX+/3jwTyRLFaLbBU4ntcEa74gwBlQjgim +rGi1IoHwGFAA8MvKERtGfC8ZrTuHCXiXkBSOCicEXrhApnm2YRLWwDRNSpzUSzZ3/0dKAhZq0/5f +TZMvzgnx3dTsTZzTm/pb2vqo/5AywDpKJnV1NAANUNuX7vuC1M+2SUiyWifXgaXrB0s3eM7Spcbk +n0Y1G554enKqW3HRoT2l+wAQVYerWlYdarWFQlYVUC/ztkVz4hwC0K0VLksRjPHgglqehqJgLSDf +u/u8AHprRToFNnetXJRfy+v5tXRK9pYA6KnNsaGb6ZNx29qWBKLGdhAeKYo8B1PBqJwfQOVVIFKq +MriGoxj+JNfO58ifsNR/H7kljfrPnAKCLyN/7P/52XvJh5+meAMX+XL2TsFjxi57TIDDCkimfs5e +8sReiWSpnzMnj8vqHtx/rYud+Y4OLH6fDvxhi6F6UTUDcaaaxXqZ5WIe6NXvgZb+yTSpexESndAD +lTO4llxuMxgPAWDAzhAQBwYzlh12FxP7QPEACHS/5iAKKW56WXAqnAVhIltsDiRbiNUm0v7ZVNon +G/RpHy1lUxHd5JPp+Vdmz8/2DNh/Tdcl648eVV977SjdEpbIoAgy92NHJMZkRBZzLOZZLLBYptge +oxBh2hsoB1RNcZzzYFlZLJkOLpkOcITtaROwolnd1U4WCWCtYQfo2zCYbE8SfRoD2EMOkUbkRipp +1O0ZNVE0p4s9FtFVzsTpitPMNAGSMjrTksPxDCII6hsQccr5JCjzVyublV/DUCpTlalOrowvsQ92 +NHGX8Ffbr3Vsscs2Isi19pGOGWQaN1HS5en28Q7rveQ+bqe0U97NPSGJbuJ0OIYJBBgRkRW7fZgg +AygrFzsvxjomRJYtVhswc4dDpfPU6m53E/dBshvEyvAuQZN78fC9isVqOhczHkTd0mjVdGWDDdsO +Qrcd2AZlSS8kTozGWXMWgxDTHxQq8JHmXKNitZc07teEVqFdAElCdne7qLwuoK9JtNT5+ykCM78b +nAVyTk+2UPytY+8FmUdA7WP+uC03MXccJMOHoazbrekXSAEBKaffRCT9JnO3TUsqcG1QLqOyp7/q +dFjpxcxurzf2RWsdg6Nsx9e+mlpHZQ0D9w6B3MyurkTz2rYW4CZ0KQnR+bJTfi7QF1qJM+Ogo4ch +tcCS9I2swVFQG3AMu+7FxfiSYd6CEXgBFg6lGp9NNQkHv/3i7vMbfsKd/WYy/8q3I/gT31KO8ADI +uAi1bwhhVMn5TQexbPreuhrdNlOBkv2Kly36f9yTAU7rMZdr/BxZYTEBuS7JIIZkInGcbOEJsUgy +z4Hq921W9eNyVD/OzN8LPEoUBVPMC1nVTzBoHTQyPcAIrkWzYc3WYGu1rbG12wSbnGtrZawvzdD5 +7NDk/87m4r+r9mVtrhytItGSqGP40tJ2+t/1PLb+UVu7hWfIYsolLn1iP4gjWYMIsY1Xw4dR3R8w +oUfWJ9fCEB7dN7lW1isNsLJWAmlEHUv7CgCsNECaGzPeb7HFaiVHPoQ8en56Xx6AhQZYCKCHgl91 +ZsUTzqF6A5EUTkZY+nexZHjxqjBVPbHrgRc5cvDFsynAmo38BsCY9m/b6TdJwCJ8R3gDOVAQGzrR +tIAT56v5+UFfMMjzKp9v89mC/JO+fY4XHJzP5w8SrVB3zcib4dMDTUKTZa46x7Ugb55vgb8xMDd4 +h+8+ohaEOc4dtlk8A+wDTw6SeEz7YF+jJ66B7f3LnFdJJMBFOr2SqRhKdJMInVSJrojTeZXMZXmJ +TjhjylKgvRAXOk2R6TRRyJm1IJ1xijnZt0wypmReIxJz+G5BaNE5i9z007VkkWX6v7960tLSFuy0 +uZmDzmbhCpg1x3E5b5PQVSzq32FWXI2KqiqRq5rEY0VoEd6KR76CJz/dk9p35NXUwd2/xoV//DMO +XvfJ3b9N/ZG8jK/AP30u9fhf3kvt2vtrPO+XqX+lXsXVONiNbT9IfWB45vh+oHU78uOhhka7xLUy +n0xTp+Vfol6Sz9uUMDBy5PMbfg33gAn53g3e3Y3uuHwIpsfwxjsaZebxltWMUDytu+k4yQEtgOEv +4LebI243R9yeVVLs/68Oku+6iwpydZVzXvA2Y0oy02H6i5hRRk3uTofCHCUOB3WU+L/fUVLpCxOY +l2jUBXDW6UbK7pm+6p7mz1IvpbbiGw4/2HLh8NtStwsHHe4l+644lOrvf4bD2zbMv9Vjp77Rh4Hb +7oEZ8KMisoHNQNRtc2D3yNC8yFL5ighvYS/UyCyWWFwMTIFhM3tthQKKCdhMwN2bfr/bHaiG9FR3 +UWm1i54XllarmdSZSeH6n7oL48Z1KK9mUnpdnwpAieOC0AXaLNv80BWhtZZrHdc5N1m3On9sf9LZ +6/zY8ZFTBdrRXM58l8vpcioWd5BEA16r6KZvugh+i8XrCxSEfb9MH83x5x41LHafD0WLGF75/U6n +Qw4PQK6Bm6Wy3oBw3PGAaL5JJ5qYwNwABcwhILJVmRateE1xezFXXOQn39kZlUUv/3+LXuJ/lAUx +ash81/+WofiCk/6MT5gqDhksA1sHTmor2HstxmstQvYtw5wfytisulXWnbVOdbTLPZqybNzGdAYH +cP5AQa0LZIMbgkMP1apgkqhFEQhZZt8c7LIUUBeRbltVUICwE7g8LmJMJoPPhp/h35ZsfF5fXowb +SgCjYwy72Vaq6MOk49hvrn/59emD5lyYPv3cnCvnDolO+yt+eNPOi378aGqYcHDGr6974M3CkuKL +rkq14eG3bRtlk/qv4qpqrpuynL7BNj/9Ef+/wutoGDeOrWW7UGnOrp14Dpzd9wrzpWZmsMAEAgCM +i7By9pw1QCUHtuXAoRw4aMJgC/kzCEFMABuAPqhxEbeIX8et5/mS0hFcbWgCN1W6sHBSZGLx5NJZ +XLM0v3DuoNvzHDHqkKTIU2wCJSYQN4FSE4gxvDIKG0CJCcRNoJR6MCZTaJA9XkyKudKSkc7q2MSS +SRXztMbYnJJVthX2lY6l+Uv819mut1/vvEm9qnhdyWauw3a7vcN5p7qp+NaSe+w7nTs94YyZMiQa +dwfjAUu8DMcRKgu4+crhcbQEWI99yHXB24MkWOK1DwmXluASwStkl1CE8BBLOOzlmKii7sQWw+9J +kxb2jkxFn3EE9SElxQ67TYiGCsNBWQIrl4i4pLgI8kQhHBwS0CkNbQde3+dFQ5hjmClwKtZwA27F +a/AOLOJenNSVIWEtL2/8HFqxQEnaTs9oU6AHF1gGbKa05PAHy7nNlJY4KsNlVMw7HGROGe0PI+Gy +QGXU3PgVNTlB1NwjCWOE426qadK73CYHcGd3BbhnU0ZRMDzjLG6ZfjJBd0RnVuFMuc6W4uiLeGp/ +S4LuiEmcpiMFRE7VKbqS2kz3wrSdo3Gce8IoPrgfB/GQoHeIwEzoITZvmEkfL2euVAC5GlvDwqSq +MrPYU1zKNkWyN4gya3eefJ+X9zF6FkFziM/fb1/w65tWPzWrYf6Y1KqZly+7+YsfPvr1ZuGgc8+T +yYdrR+G3mtqv3/ztT19M/fM+/Ef1yjvnjl83cdKymG9houbRJat/tfjy32x03HHXxktmVFWtHDRm +79VXvbpuPfu6wTDQIg7SPSrYxywG0WS5kgmIpvdR+r96H0XT+yj9X7yPwL8FEgZkQ+wT05Zesq5b +M7Zc7Bc1TCrorleM9+KMv/dj3cb4vJxh8l+Y/o33TW5/1uTuKcNypk+U992X6+qAqQcF/2TLhyp7 +s74+48bN/oI9SBbZi/+gxDH+WlmfeamGvfGflyrkO1JBwb5nzzf/pGP3MOjP1Fuej8cYX2+IO5v4 +Jvklmff2Zvzm1fwYeTJ/gXy182fCx05JQcRFXxAVLfkDBGZ+DkHkmwKzuzE/TkwLimQtKKJmVk9O +GBYUadG8WPM2eEmrd4233ct5/6NWtq/RzhZSTPvPqmXemjKkp9WkHWtWelr5jMfCkJ7WrPS0tnio +JXVOehqewOkq6MS52lmf8YmHBNXLRBeM7b5VogURm2GqUGUMV7ky+vEIsFaMvb8uvvW5xalv3/ht +6ps1z03Zc9Ob+4SDZzvfSZ199C5s/4SbcbbryN7LnmPfAkAW0MIm07fjwECnGCwMNl9xM0UDD0BG +5MgD1iy+ycJogAmSu5bxRVbkmINJHFk6sKQ/zUo92YR7Gq35dvsvM8/90MzExZm1bGIC1oBpndNi +mV1euNj0+gOQ40jT3XTdj2nyViRYZAEToeKd4+o7x11VVciw+ujm3uIKAZejQVyJtUIZprQqt8u3 +W3YoR5VTik1TGhTCE5tMMhueLVixMT9ffT3blAR3Wy0WTRbyZVlAQHxEyCdEsEBVn2hWJFuWyHgJ +JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRl +RGVjb2RlCj4+CnN0cmVhbQp4nNVaa5vjNhX+7l8h7jZLXEuybrA7sEsLpdBC6UApk6U4sTOT7kyy +TWZ3OuXy23mPZE+cSEm3tHxg9tE6kXXec9HR0TlSPs8qRv82l+ytpmKX2+zZeca578ND2IqZqi4r ++uPs/CZ7azGpJnjHzhfZRT4VQtfFROgKHzUvnp+/F0bwfsTjM7zkj4n67OHlA3mg1CAV+Kisxwud +A6oUZkDl+4Q8bwqdz4tDWFEq7YQRjJdc6krU7LzN8k8f/orzz7KJKJ0UrrJscmTUaLAsgYZ/NFZa +brnzY0XjkXZvRSlUrWqPdAHBVL4uJi7fFhPFHalmCtk/SWZRVkpoZ1lVKkK1HpUrQh3bkIwnzobO +XknQ8MrUwstUBYHMIaUuuZZWCnCAgNwKGkZw8hBumIppLiJr56siGo0Zk4HiUZgKNS08ofOe45jU +phQ064JpJfb95yRyQH0SHsGhID3n5Iylpj/jlbVEunPU2hIPbi1T0pTSWGOI20X+cWF43rEZzUR3 +uVwFcdcFr/JXG7YtXH6Ltt4UE1nl92y5Yh90d+yTQlPni5KdX3WbIqsBsV7N4W8du2u2rGGXy801 +ewHS1fpuxWb3rHvdEQjP79erjjWrlq3WoOlK9m63YVddg7dcZPktC0qFmbPOueAvkBAydSTY9Xp1 +2bXslj6v2XZ90xHk3dWazQvTy+7HtSt4k7h9UKO5L6cZiXzPrtevAdE1cxp4xTwRDYE6bFNAH//i +xXW33V7fl4HmZbMkrjSIvYTWMNlyTmNL9hG60nK3zYpcPchLlvUzt1hvLrtbdrW8KWGUHDZg7YaE +fw3oZksj8bajGbD5LXgBAeMf5F0ti4nNL68KrJzbwP6mmJi8aTu22HhTLbtVu/WG7lbdzbLbkqVh +8WlG6Nf3R+Tdkic0d545uQOEu1pug9QQETPc3Gy9QVY0faxt7jGWzZsbeBHEszl5xXKa3SyJeHXJ +luQPi1cea3UfDLhcXQbFn726HVyjCq5B/pMW7a7x6oJ+vodB2l/3sYSmkcwKj7Y5sLd4t1hj+CsY +AjptuyIj11h4y5DveIOu74JcxUTngYuXYyfZvtQXXD73MiIq+RVmscKYkXq0ki/yc0/6yR9gvCp/ +51e/L/D4wH85D8vsPLz5qP/qQx/ivMvfb8gHvZZFlt40KgpUNZo6snHw/CLab4hGHwa3/LmPFWGj +w2MXKwxXZSWV0+YwNI0DB7yJIgfzVu491i9NmE64EDTIaiFwmGoIHHD3bgNvFMpHD79ZGR9A8CCf +2XmBCA7QBxWT0+D9uOKdx8efhh6ILrS/BNghxtAybMK6vY3B9wMMmIQYY0OIwbPzvRRoiPs41rhR +qKHlVQ3RptdyCDeeJ+03+IcHXEbU1dHkoQm2pejRdovLq+VnL65vVuuXXs7PNz6ovXp998X9lw+6 +BE2ekqM9+yWsz/O3C+97v373N+/99nc0C+9/QO7tfRGOiY8fFhj2Rz/4o/M//dmjf/yXT/4aHG/P +wbkZO3iO3UvWShvrDnfWC3I00zuoRrNo7mwiqb9Bm6HN0VpyYLQu4cRT7MmU+vjNNF4EoFpAEpKG +00aKJtHq9HJQhvBqNIWmv/Pd731/CpIf/PBH03xa/PjRT8g2k/Ktn/6MPjx+cvbzX1xMp8//9unf +//HPf/07cpapqCFbDdlqiQbMGmlabaZCVWh4p/BO4Z0CT4V3Cu90RVkgGvo0aDSldug36DcYbzDe +mCnUQONoAk2i1WgKTaMZODDmaio5RnGM4hjFJYmNJ0ZyjOS6/w40URXcUqbIadLxFOSheEqEQgIS +dd+hivBdU1o5lRIMJBhIMJAQQwJcAlzq2B5SgqCuKH7iyfunoD0JT9l/r/un6vvBqDYFdcFsEmaT +MJtUEIyEh+mkAj+YT8J8SEPReFCMMmJHT9k/a++4+KD6DhDBthK2lfAjCftK2FfCByR8QBq8NyaO +riOt4GIczsnhwNxQRERzaHBgPgvOzOHEHE7MO7RF6KO8TsAlBT4IeZaFTqwE+EYFH6gw3xUqhwoJ +diUAJrAaBIAEgASABPxaUhoKEMxehYmoYNtKZgCAFSooVUkASABIAEgASADINkggASIXYfXVPPTV +AKoBVKOzVhn+A1ANoNr2AwBWA6wGWA2wuj07mGUaBOR6EdYsMmxk6GgyACggK7xQAFYAVpBQAVQB +VAFUzftxGfRUAFKLEBw0gDSANMTTANEA0Tq1jjHzAi6OsJMMCBpcNbhqcNVN4KbBWUMdDaYaTPUi +RCYDpkZETIgBVqIUqZBm5Jm09ISQRvWfoYEBoLEJcxkIYqC+gRAGQhgIYSCEWYSQaCGEheYWmluA +WmhuAWgBaG0yJkqT2tUtGFkwsmBk53H5Aq0Qa/qFe6iW7d3GdkNiYSGfq5LGqVKGcdDDQQ8HPVwd +0Bx0cdDFmbQeVVIWB7O4fqdwUMjRTkHIsJ5LeaSDOd2CdpUkG9TL0vjMCo3THo2wL5Ksm1QJDgoE +ZURIcr0qdjuii6pPIkOsFhWYVirNTCaZ8fQZAVmjgX80qWQPVBBRpvfIBjPQpGaAsfR42L+BMzWw +fQPbN7B7A69tYOZmETbuGWZ7hjmZYbZnFGPoidmegdeM1lZGAwA0A9AMQDNQzQA0A9AMQLNFYiIp +HZiDcC6CvnOgzoE+V/13oM+BPgfwHMBzAM8BPAfhHMBzAM+zPgZTXtECrIWYLYDa3ilbiNkCqAVQ +C6AWQG0fKVqAtQBrQdx2iJAt9O1itwoZG0dkRV4sZKmltbUN++D/tJweVUW0HfTZ3gsC/1pVNtWW +fd6+K6dRGIesPc3lSJU9znwP8l5s00Pii8XjS9fMxaW2olLb7SrtNPtU/X1QfvtCW+8KbZaosadZ +XGWnGYba21Ht/U1K72m2X3zHpffYxsnSm71J1W1C1X0DMuQbuS+600x8Ke7BR6U4leGeX/AfqtqG +UhzVmKiiojs7WnUbqrqP6BdqcXKch2L869fi2bgY9yXK7pTLCab1+Dg2v17e9BtWdDy6iI5G/RvK +kfP4lO+LxCnf/ple7fSpw7wv4o1zOPxtsOGh7H9M0fLsQCXDS4c/7RhC1gibBs/ijecpGext+u9Z ++rTZs5nzgTUwYis8pYPYUD8+iywxnOjWbHe2SyeOL9P6UToxm58dogyT8PkJKZvmCFmVbzzZhMuy +pjNlxSbhgPpp+sSU508Kjvoi/zRiB/Mii+V0HI46y/L+DHieSKLY/h9FtXgTJdoF0Q71OHW0/z1Y +W/3/gHXfAIzHR/jacM0Nk6VDTatUOP/3lwpYCLW2RvkIw8N1w6H7YZAYDSD5bMwDdRjK7hGOv19w +JWpHVETUjxzW8f7S4jV7kpZ+ER2qMfkTVrPEZUVXxWM9zyGMcOevBmrJlFElx+JX8uF0aJR2urO9 +I37hg58tDQis60NE7MbDjCQki/02mtAT1PEM2lJjaVrJaq9Q2AZCTn4QkvPZsZuON742i0LELBHe +h5s0t3eTFiMcvTlDLa6P3Jz192ZWazqwPnVvdurSLLJMc+xwVhtZchTtysRHh99+Ghqd+Oxd89g3 +TEAjlFMZafqCx371oWvE5fDGh/s01B1moScvfMJJ0Rj1ZZ/s+eudUQ6qTuegBxloljqL/tayzwj5 +MB2tKB3derqHzHPIOutx1hkhpdJQt0tDhyx0nG9GGMfugg4S0NO3PlkeZfKDGU/eA71Z6hnP+y4Z +JTGPXQyNfiOgSyqSEQoUclMKz8pF2eEiFVJR7sdJZ5ybXiC3TKWyEhkqNqy9m/XhWVfp7wf9bPCh +MT8kXXTipVnlA3wd8r9FMoS/eTZNMUrkj478mgGTk4rnxcPNmU4TItQfyfP1183zx8PoRxQSVhj/ +voBdhTv3EruwxiSWdGIcXn15CJpjXkTpUpPuoi174oibrmkj9QZ38U8oDtUZXfhF+/Kg/qNo+Ghj +jY9GB3M//Pyg54+Fs00j+Sz+xC9bRgqkJamOSXK4iW8RcU5AHBfhOOERK0zqkg45K5pgIWladhs3 +0lIkk7W0o3xSpvJSg1H1V+emtaCNfoelD7EqpBuK0kPKkQckN2RxI/RU3+zYuLEUUNLZGgFr4BAS +ZMrApa2scqfEm8Q6HFNVcVJjh+WvFN85zz7M/gOSUtWRCmVuZHN0cmVhbQplbmRvYmoKNCAwIG9i +agogICAzMDk0CmVuZG9iagoyIDAgb2JqCjw8CiAgIC9FeHRHU3RhdGUgPDwKICAgICAgL2EwIDw8 +IC9DQSAxIC9jYSAxID4+CiAgID4+CiAgIC9Gb250IDw8CiAgICAgIC9mLTAtMCA1IDAgUgogICAg +ICAvZi0wLTEgNiAwIFIKICAgICAgL2YtMS0wIDcgMCBSCiAgICAgIC9mLTEtMSA4IDAgUgogICA+ +Pgo+PgplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvUGFnZQogICAvUGFyZW50IDEgMCBSCiAgIC9N +ZWRpYUJveCBbIDAgMCA2MTIgNzkyIF0KICAgL0NvbnRlbnRzIDMgMCBSCiAgIC9Hcm91cCA8PAog +ICAgICAvVHlwZSAvR3JvdXAKICAgICAgL1MgL1RyYW5zcGFyZW5jeQogICAgICAvSSB0cnVlCiAg +ICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMiAwIFIKPj4KZW5kb2JqCjEw +IDAgb2JqCjw8IC9MZW5ndGggMTEgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCiAgIC9TdWJ0 +eXBlIC9UeXBlMUMKPj4Kc3RyZWFtCnicnXoHQBTH9/9QllvuuLOuXQ5UxK7Yuyg2bBgRRYqgFKkK +SBUQRKwvIlKVIoiIIhYEERVBwF4Se4mJ3fSYqPHrLM6Z/b89jTHffH/tL7LsvJl5OzOvfd7MGBBj +Y2JgYKBxnG8/ee7E8QsGTVgW5E0MjAkhBvg7XGxGxI4GYidDsbOR2NpYZ96JLepk4vV2LNcZW4Q0 +wyfJaY5Po/Yt5HdLfHT/piUxNjAw7zNkhN2ykJgw/yV+4RY9vHpaDBxgM6SPRaBPUKT/0j59+nz8 +poX80Y+lSRFhy5DTzazBh4ZW3PEYuMhr2fJsmyHDelT27jlm+Hwfi8VL/JdGhIXHzIpaENhvrl9Q +pPfU4LQQR98JroPcZ0+a7DAzIDR6xXi7iVPsp02f8dkcp3nOLgNGHDtRW2fZpWu3RKvu1r369O0/ +ctToseNs3RZ6xsbFr9xRtHNXye49pXvL9h04WH646kj10eM1J+sbGk+dPnP23PkLFy9d/uLLK1ev +Xb9x89btu1/d+/qb+w8ePnr85Omzb7/7/ocff/r5l+e//vbi5avfX//rDRWb3jLduz+kz/M25hSk +bF+/dUtSekby2nVrNkAuIcuIQPJIW1JM9hBb0opMIBPJbDKXbCAtSRvSjpiSUmJGlMSctCfDyWSU +gh2ZSqYRBzKPOBIn4kL6E2cykswgzcgQYk9mkvlkEulJZhGefEYGkymkKxlNWpOxxIZ0J9ZkAOlH +ppM5ZAFxJV1IN2JFepBepDfpQ/qSgWQQGUqGkRFkFGlBOpAssp3kkp3EkBgRY8IZbCQmREH8iIqo +iYY0Jx1JJ9KZaIkFsSRjyDgSR9yIO1lIPIgnWUQWE29SSHzJarKXAAkg2WQXSSQ7SDzZSpaTMLKG +bCbRJJYcIGVkHykn+8lBspEcIlWkglSSw+QYOUKqyVGSQ46TOlJDTpCTpJZsIqdJA2kkp8gZkk8y +ySVynlwgX5CL5DJJJV+S6+QKuUqukdvkBrlJbpHd5A75mtwlX5FvyD1SQNLJY/KAPCSPyBNSRJ6S +FJJB6sl9cpacI8/ISpJAxpMI4k+iSCQJIaEkhqwggSSI3DLEpe+Ci+SMxJP40e/JS4NxBrMM5hv4 +GCw1iDXYaiAadjCcbnjW8J6RyqidkaVRb6PBRsOMNhm3MLYw7mk80HiU8UTj08b3jJ8Z/84Zcmac +wGm5HtwcbhEXwH3H/WbSyqSjSbBJrcktxQJFmGKv4qjiNW/Me/Ah/JemVqZ9TceYTjada+pu6msa +YrrKdKNpmWmV6UnTX5STlbOUq5VXlfeUL1W8Kk21V3Vcdd/M3uyI2T11sDpSXa1uUF9U31Q/Vf+u +0Wi6az5v9lmzRc1imiU1u93safPhzf2ar2qe3fznFpNbuLd0aenX8lgru1aOrYJb1bY621rRunlr +j9ZrW6e23tb6futfhDnCEmGlkC7sFc4Ij9vYt2Ftm7e1ajui7Zy2i9qGtE1sm9l2Z9uGtnfaPm9n +3K5ju2HtN7Tf1r60/fH2V9t/26FXh5cduY4dOvbvOKmjZ8cVnSw6ne90p9P3nd50VnXu0LlX55Gd +Z3c+0Lmu8/XO33fWmbcw720+Qbtam6Yt0pZrT2tvakULM4swi58s3lqaWnazHGQ5wXK65VxLd0sf +y+WWqyxTLIssT1he7WLQRdVFgFrRptagtpbW1xrVthG7iZm6bia1Oi9BtKH1OhuFpoD6CaJntc7T +RPOQXmwyFViRziUjUowAOK8bBdSJPgLd59PCIIYmAuTPzgXxMacJrdopdFfSkbRJYNeq6TUF82X2 +SNGUUju6Wygp2plaBnxdnbdV30DvOW4u52hnLdAAqqCGVHWejy3h2JCZzJZpgS3lmc0VW9qJtvz6 +W2r6q8MVZmQ+B3xjgwN5zURq1+Qm+Ck1offpG4Hms/y9e1k+zefYCWOKf4OwxPI5DVthLK6v1q03 +0VAP8YogkVHGthLpyeq97PALo3uxdsyGmfJbFolqyKOtI1NDvFkEcI8vUBs6APD/688uW8F0cIpy +9OWzQ7nKzPwtx4HXbKCrRXthqrKaJQn2Ss08uk20EKYpNWU0V+wqLFCmHRJclBpHGout3JUa0UVe +zbftqv9oZ6IZRQsOCSD+xhbEQsyjBNCd6CMv4glcRE7jVpsg0Fm06xXaWwtXg6pm7fLI/2zzaOCL +cE3dYOs3yVtZPCxkFzOjuSsgEesbP0nSu31dJWLZp40kvXK8L5G+msuS9Dz4lERULwdL0u20MbCE +H+xhy8aZa4bkiceEzBX0AHATmb0dGzSATeW/CqFRTYax29kTwCWbSHFBBaCuDbTN3Vt8XCHXf3I3 +Zg3MG/8/Z9a/TOZzCrmxt5xoG2zEa7rRW+IKASrDdy7OlaSXk8ZIhDuZLEk/HccRcLZxUZ9X5hwr +gzPQ4LdvCsyDoLglEXx6BFe0ZVtKIeyH4hUQBO4rli4K4VMiucKNWRsLEiTSrmcWMksskQh/O0CS +fklwgRB+wVJvJpj7KmhXqqz+UasJpd7iGEFnVi2ayYrmKysajt9eHj9zdWJtxo7ncyK576++otZA +vfF/T2rd6yofF8ndHd/A2mAjHlWWdpF11sS4uyzARvpE6I0i8xWPiD8JdkqND00SuwkzkXOk5hp1 +brIXmD1K7noCvDOjZntWneHoFdpeoN2mnBltPhjcnf28eTfF7vJ9FSeAP1kRyFqwzk5OjlpfiEiJ +2Mozs6XckchLa24DT6depAO+02q20HixhzBLSe2sBAcle6cbK0y87vcvan3/7i1zuIZL2XuJRHr1 +6SlJWTe3SaTNjTs8E3ZzgWmxGbANslMzd+/kQ7M5r3BPZ/CDhUXhjfF82WqqDuEqk7bHQjDvEebV +e5xbaZ05HM7NqtnHB6ZzkauGB8IMnp4QNwuzcXK2dNl+YY5ytnhfcFRqXtMgcYrgrETbdxfHCx5K +zVSkTBTclBorNKVqYaFSE3aEaYRVyav6coVr8zbsg1Ooj92bOklkUsBgiYw2eSaRjMzLPB0qWl3M +h3w2EiDmTJw129qdZlfnIiEYCSfj6WidFRftIklvL9dJ0ottO1DugyZI0lNfD3zLDZekZ/2PS9J3 +3p9Lknh1cjjEgW9WXAqvocF0zBFhpJKeo9bCKOU9FNdopYbmiZPF/oKnUvNGXI+kicpi5iJMUmqu +VjeNEJyUtDe7IMzDCUehnrcXLJSaL+hjbDceu6poGIr3M6wcKTeer9SAOFZsL3wcfmNcT7a9O83X +Dz8UCfXxdIyu5xG0m4Zq6ipMV2L7JGEG8kppbGopDEZFUje1RC8wFPzdlzjxmV5cSeWusirgj+xN +7Ic+KGJOBBp/5HsPSjdxL1zrh5jrRm4Q2ERUsi8SgP06VXYPsdjCCVvkciVVxaX/Q//hEOrp58xr +2NnHTZOFRKXmnphHowRXpS6ezhX0bHW3p4Zjx83YcXwuNPGcZiflGwRbnHt7erVplDCCaWzZFO1G +mBoBsVcA2C+T5HFkYYfR+KV/UQJwiOGjgoPLn+/M3J+1NTNlJxTAsZictXzOlm2PuJjUqJQA9Ja0 +/xlcC4i6FQG6mrFhEEVLgKOzrl+mGi08H3e0e8bFzDsn4SlPDZwqWT/zcN2Pgp3YUGtyrzFsYPf5 +wUO07ouvmPzaGNizl4tHd62GDaA5TeMF1ufdTdq/yGTUVmj6/O5WTuMlWtAFAlzxr3DYEZG+fPPS +z2uLrp+Hx3DPuXYYzATXqHm+fE4YdyAnO7UKjkHZciROi3S0W8SnBnJHN0qkxTY0L9KsuUTMfZeg +13nxAh1r4A1J+tlMIxGzjL6S9Oj3V7CQl6Q9fzQ6SdIJg7FsqrmfgrpR63O0pzy2Kzg0CL+7Et59 +PmolhNP+AE03Oc1Nukb8Rag1eVa52KqL//Qu2jWBaSZ0/MMnVENNZ59ivbWsJMpEv0Tj5SUqBCgY +gRHhFd0g/iDYKGmh8UClZjdde0gQG+lMRcHAqhSgrXWT4cPC6nvtwl7cEHpAoB1gh+MhANrXByIc +WQfUUJopthRfC2OUfu+IMBY1c3RTC5QLm6wLZXZiqPUc6q2rO4fRWGzgqEInB6n6q7lQxPxhj1MK +gO7Q9HD8RIr8iXfDiwTxQKrit9NsBUD49VjQ1Y+Sa+fKtRo2moaLv6EjYVPYDGEuKiAtQSNg1sN7 +sy6s15NZT7QXoXrHgUP8fsXS0LBEN+AXOh6g5rRV+ckr2iooWFucxFOzEm55hk3+CPSUzu/UOJxd +hXcjgZmFZLqDrlCvjuv1UXMzjaJJAgbzhdNikGiFRP9cakCnctvTBUQWYy7K9toW7XVH/GBmzS1C +h5G/DUmOSDq1gpoyl4ds6MoE7DsT+zrmM4Eu4zTO9MeDwiK05Vm0samd0Ee5W9dR6IvlmWL3BKEf +vqQ1tumvpHPE28IALC0ToUoYpNRYUkCRDUFTUtJkfBuKddP1b8OU9Ix4Uhiu1NzRi3WEUpbKF5ME +tqkhxoMutc6Ffbc55oBe6KOYaDe95ozDt4XiTrpBmIBvg8XL4s/CzXwoZAsBIm9Hs166hcxGXHhm +O5JQRJGXY2mYrqlBlntfeomKAlvMrkyKgkg6FaBwfiGdSo9wO3F5RtCsK3KnIdjpYBTTsnhuAF0l +HMpFWjjS6uKpPTtNe7KC8ETsvQh7L9jKfOkrTvNQXFgtTFZqvqV1OJnbu7owB3RJLZLdwpzD/ePj +PMAW/F4DdQDaYktNcV3R/p3bqoEP1b0Weik1mfQBpUJIePTaQOCd3fe//LGk4vTxageGiJAFMAUz +ZKpZfG4IR4dcoLYUYeJSntrMuM06sZa2iNp6nJvxL/PTUJZbWoaergONEc2FQFyaN02W9JoQrNSt +/xrL9IHYRViqJ2ua8vBtjA4QOLJ31PJD6/dk9gcr+gTE2MogJlEGMfUyiEn8/wUxiTKIqZdBTKIM +Ymz/CWLoT2wMjlbD3O41aYS9utFfpu8Rx8Zt4Vx02+ToxAbTeVhhqWSxsfjUuGRinBG5Oh1nUkPb +fHije+hQoYuS2WfgU5NIuetC9LceGzaz5tyR+PqkS0C7wpWb8B08tz9qcWL0weBiaIQLR/achEoo +Scpfw+cOP7oJqDEXkeqUPRmYEqbYwwjoc8r5jctjr8IwmAOzPPxmgw8s3eKVz78UJeFdXmlTnkJD +O4vdaYiwn91VOMdALCeqqPKvEv2WvRK+h2sF+3P4NGrskhLbl1uWFL7eHXjWaforOp4Orv+NttKe +gEOrS+L5zCFVkEqVnP+26dvGYBN7ZoDuwo7NpwaWdIRWI9o1DaGXhK7KWHZH6KbU9RLffiyIbelb +wQolGkCX0G8FOoNFcm5+oatmI3xfcBYuQkPWibpjfOQOwW7OlBkwBGzO21IDeAr1R+rP8jdsUMGg +0PlgnzfcsS+rf8o/y5+UjWIOGsD9KG6dZ3C/xQ48ujVX7mx1+SH4gm/0Pze01/xpo81h1mHXfT78 +nVph2T6fo3CKP5q/59DBwqWO5rAo3iPAF5Xzy0q9BDWe1EfcKlg8iN0Y6pYeR1t7Mm78+hUHffJS +vqbkIGuTk3S8KCVvDDXkaIc1W7OS6+PSWGuv47Rlcs78zIQETgYtZrStYI1qMesodRN6yHpD85om +CD3fIxpxBOoMO2xs8UkxiR3R9xhJV4gTBObCXCj+7tvPxqDtj6bDke3Ib7EmwJ+OYSPYaDa8LIBi +Gw4TGP8mc4Qu9nOXhfDbQ7iKkr3bGqABqoJgLvhLUlNNgyT9GEDwMXGcJH2bRfhuTAVh30zZvi25 +5vELTiJa2YB69cJHZ9moet6yhbNww+s6aw18zHsNp2niALFMYHPZWNaHebBgOtyGDtPehUc7Go7w +ccWcg8+MtdNQHdox7U06nzpgtqiivWmPn2yZNTNymOSujYbkrC0H+Zyfy6gFh6P5AT9lUlwvSdeu +mUnE2NUWaZMPI4v+3ZkFMxlXFVuhPQoV+w8/5VfNwQ7iQDTPazRRIu2/wLff+MQaDDom1PhHOoB2 +7vEGgVAUmy/kQd7qrER+XSgXYOE1eTnw4cm51dczv72Dcd9tB0phURxNfOdXlcNp1qC/bxDoYNZ8 +dxmbTWey2Wzm7kBOM4RObxosTJHzlEaaLZxNKvBNHsonMUMuyaJy3tNkPqWQ806Pq0h/xmf8zG2l +3JyDi3Krck8fXEk5PulnbvWznIqKdH59ITco2WtehgWfgV3Thkb5zk5CRTvwVVOW8Edczds4hZwI +pdMyYXZGVHnaIz4DlSrjjVf9oDR+fSRXsTrHe/VAPqk3t5Jxp5dUxS6KnbNkK+P4jN5c+sA4b+/V +sht7mlZZn/SGT8KuyY8Kys9mYLIkjqV7BL+lccneMAs8y6eCCziFuzry2yO4A3ty0irgPBzx/RJO +QENRzSle1k4v5iEEiaOnrl6qG5uzhjshbhMWKzUBtELMFCx0z0vWvxGfc+7MRM6fAzGQvBLs3kNP +iJ2I0PM6Qs8tCIGjxJaYojdzT40exgYirkl7hfiT69Zoguhzd/r+rPTszTL6PPgP9PlS3CTWCZdl +a56A1twYxTi2kqlpQqVMQvQSeT6WTmM/nAFu+GkhyEPvuX4CcPSAD2/jJ8jQKhuRzfjt8DV3f/+I +U/i710Reb9pT0DWrEZspXJsMBPa8hj5XaBKoD3qggJ2ca6StE0wAzIZGbHoiSRdOzpNIQJi5JH1h +u/fx4r3LwBlmuAbMgVBwSPMq4hMeeqHLVnFHVjQmostuB/fuw334WpLqxnaXyODjnSXp84Z7Ehk2 +6akklc/ZiunWMDNJerzfD5Hr+ddwCc4eyt+fzx9i8UJlKHds+zf1cA++laRz0/qjEdr+Kklbqq5J +ZOjJltj/O1OJWNtdRWzbnkqkw4kBUA2ny/cfhxI4tSp/FZ85pnITvOEiMhZsnQxdYbwtzmSsRPo8 +ccOZWLeViE/nYkm6fPfHR567V4A9uIcGu6zkUcEjxXuCl5INa+OFtp0gGoulQhGUrM1Zw+dM3A9b +KOFi0pakLwa+C1OPZwOZ9ctJT7Q1cCb7yDF+ZR4XGbcwwQf4Ufa3qZqafVF9TsueMHvBWxncxkfO +Ph0xpZkLgfHeoTKW37l16+YS4Ct3rZinjVRErg/a6Lpq3qoVrhACfkWLTmJorszbUcmnzKVt8mDH +kpTks/A79/WC3Q7m29lowUexyjcqPhYiYVUm7IRijPXP0FW1qCQS6dpRdiIz8U3983KJGCakYBhv +vUkiBolh2zbxaOEX6UrBV8nuUhv8o0kX+9BAATNH6qvQ9fMQREOortb1kwFYAjYdJ9C3NYq64si5 +E3yiJ2kRavZgi78FyA4uY22oDVebcboMvuKveR0YZM58ok0uLAf2vX57bbaMcdlXmNp8WAMfqkLf +sgR9iCft0tRV2FcaNlcLy9YmxK9IXLUqORwCIFAO8Lu3ZG/Ly8rMSisCPpnNEb6srblxe3rpoqku +bna2F4OqtCisYPRG/krNI+qFaT6bsBpiLsWDbtwqNikrjnK7g6g/ty2ucHUOPIC9R8rreBhAbQs3 +5rmkJVwHeuvPDmwrF+LhHyDD+MhdD7SaclqFkPWy7pej4g8mt3ZAAUsCjnWdOoyZMtXjmbS9lmUc +RReVga68UY4BQ2hz5ikEKDX9qGuTlXBwx8LhWnBaHxIXHpeQvC4SlsDyYziEhtSSnKKc7DTEXHw8 +2y9Qg7MXXlMD20N2zGDOrC7M4Kb3DS1K5i1dIQQp5zMbfGIUC2bLhEfwRePuEj66hPMOCYp3AidY +tBfXaD/KeCIKuk0WCrpNDQq/QwDhX1EVFI+8Eh2f5jqkO8aHRxi7pFu38PEE45l0u1c9zAa7yokU +o1j+e4eGSUL1W1P07AMGfZIpzBJVSPRXMkuc3idk+qBpl7BMeX/c39ouaborhCjZDDb2b211TQf/ +NKjXrPe/sXkuhCp//UwIU7JWrP9fdSLXlIPJnS4r0uRW5AP4kHiLnpBFWy9OXTYQkzoQT9DpIOeR +HNvAXAR0ONmOR+SU0RMSHFk7lNgb1lmgxUdYgQldhC7NGViernZUBKYB8xEtORShbs+kj3FqW0K5 +q2mXKqEODq8ssM3jJdLpayf0OZ1XIwZwSeiIVvMLeqkJLxiG2PXTJWJxOEMimuALfDo1c0pZYc2F +JPonu2CE7jDkJXWiU0/9Qi0QFjbGlSTwmQOOo9tozfnnOOQPArYMmDHrBmw+SNJAfoJEfC9skqSM +UR0kUtMpU5KogyHm51fbP8D0PLgoM4YrT8qNgeUQsSJ00WoeE+oyvZwwj+j0Ma9+RaX3cprFUj8h +XtdLqZw1/4T24i9pnGOuHyssaW892zXIdYhcTNAzdER++uIcPSs6CnnpyyF/saFzkM8QGQgdoFeE +5Uoa2CYcS8Hi6vf68Pxd9j+3uTLpI/335iPDv3LFTHGw/rNWLPlvVMX7r6uZ8d/Iqe8/YMUW/41s +9cnYujGHv9W9bRotSNL54RjPKmML0DYuv+qF4rx/UpJOq3eisyzZidXnPgPmA6wZawmYRErShlVn +JNJj6TtJOtQjAMNh99OSdGXYNJTThQBEjlXm60ojMTC1miiRaf2iUWdsbGzkvZbO2HY84stXDwIl +MgSDNfUB2grNjiJXsnyHTpLuJqKizfScjl/lHSQyYF06at/wKDckRnbnWI6zgNxMN2Lz3qsOIkid +9QJRae5xSfqyLoCX/njilST9EW0zD2fyw6qW2P+0C+Zsr1dIxLb5POw045dCTF93HN1Xt3f/4aIb +gMw3TzOSpNTufshYcFiLE6mIkoiZb6QkNQzsj5M9/PoVZsExHgHOQf7ey+2QcuVUP3zeqL6N2n/T +WJIetn4ukf7H5/OY09Ov9XJ8rovVZ/YLxf56CdbofvtQNnwvu526ZR8IFp+I57juuEx9Q3/T93rE +Uv7a8bxPv8N0oy987nMOuHuVS3pZ+7v00cYG5pnQgU9vUFNqPKWOddL2/1q4JLvoFICom/JOkh7u +pCPcmbyd0/xOzzbZCiOY8Sh5N3Aj6FoA8Pq9l6noQbw5uLypInN/VnF+bhlcgQO+mPO7rAuPjXAJ +dfFBJzkT57kY/eY9f3SyE/LRed7IqucblmTHgi8sCY/yx0CdmBqdwcffcl23pRt3IHFnci28hOOX +4Bpcl6Sbf8ipw0vsV2eAHHppkNflM6dQ43Z1kKTvRo5Br+3yHWKW4q2FO3N3H87eDyf5h66Xhpmz +jqxWOOSgsEMQyWk20M/0uHv+iA/HNhFKpO3SRz8rXK5PiNHiVb2tTPqEKBo0Gb23lOGfNs36C+qg +oVj9jUtTuz898yDW868azKwOIm4IXue5YXL8uLiwGeANC8pm34Y7UN9Q0rBvUq3P73AV6op2F/PJ ++dzSlcGrl8IwcGhYQ5vzNH5P2gnuN7ea0eYzEXAtWbCy1mXXNJgJblHO+q3Ng9sLMqqAb6hcOlQ7 +yXieIs7eK3Apqt6zEwSfzyeSXDgGe7ZVHs0o25KxqTSFpwuoo7CvIMBW6xneK57b9G1h4yUEzfOo +03/06uYDhiEEbGaMFtp7XDrCJR7d+MDB9yXSbIS9RCxdXRA4HdTqcdxKn2RP4EcuuCLjuGOI44pg +5zpEgYW21WnJvyMIXIwgkLUAZjoR2BAcXmDv9hJxTUlFv/3YSyL+r9A9/PGmWHbmCX5I1D36hzP3 +oW56sU5nKvmIxoeW6yXKTFjC+/Lq98I0sHhf3PGJwNqxafpjndHUTM9j/WAhUl/01POYh3nL+/Kg +9zzG2n4of/YJEyfWS6Y20hhxkUBn06ERuzDVG8pRB+YuHFD4F/tvnYpRrfXcAVaMPzeTdqLqB/dp +Ly1Q50nUkPWlxnxMBEcNGFfYF1gk3y/Y3tHR5/SLH4uOnzMvh5NJ5ct4zWtx2nv1W8NGyocyZTTi +w6zNPh42ltELf0498RNi3of5M/IXEf27npsNW/hJy+N/W5rpH2tCqzBP9RDNqhVsHRuETeguYy+Z +Sx/RHyPBvdBhaJGzeqP/fDz3Dvr/M2sk6b5TF9SNXz6TpG+eXQNmBUMHy090jfY9JNKWaCXp0qpn +qCqtMV7f3/EORXzt5xmSVJ9G5TjQ5946iYw5kYta1tVdwty96hGafoyTJL3ZtBbfZnUDagWPn8lP +iThb5+G3A2PR67eaL0nXn2OWZVHhgtradTfmPTYtKzlm54LOuoP9DGzeZnwYOvh3qGrNj2Aq9t04 +jAKSW7qzJGmb3cFZvJ3qLZF2v42UJN1ThCydGryxk4URD9S0+MJ92f87mvaVpIrATchS6fAFfnuN +Nc52t0KSvnLncJLXKyajUkfOGIHvDyKm4/PpGQxHbS2mogkWYojr2T+F1zykyXohMksb+XztIb37 +Xn6OGIz15TK96MrGvC9d+Es8jayvTAujR9/3uPZugxD16SGPOO/9Ic+7u58e8rxVctin9C8+E9/N +lfuJrUUi/iCc0p0YaWLt+IxiLkHbZB+UA96+Agx4mVUC+4xpmIotY1G03wRqrBWXfsSRvnocORU+ +nEdwbC27J1Dhb6cPgpwEFaK37Cqc22+HjExjp49w8LlFVdS04MJ9LSoasxo1GL3rkF8dX1GrO8+o +FR3Sv8FSS2vbsOZDBiF8bnPWhlprG+Cs7BhXo2NMXLJuKfBD3Rqolprl1Fyt2B5so10Y3x3AnyZB +1hnupf3REeaanTSrqVaIUbLUd+fl4y1HGoaTjVF2Z+Hy0fwb+uiTaPqQLfgrfD6kFfqeF95dlze5 +nTGxlTumvuPkQ4Eh1FUvH3z5Xm9OGnb2R3GOkCC/PH4tn7o5Yp4mE6hbmwS5dEl/GMfc2ujrLv3+ +sRBKvbHq3eTqpsnyOXaIfI6NZjdRf5VCDPi3GjGr6TLtIO/zfdXmw0PT1Pi29tOdUTN657/fJmXz +qEafvspvY/XpkiYhWxyTTd2z92wzYStAob+d1kpc31pcIWw3U35upiEb5Ds+rYiW9CaziR8JJ7Fk +B9lDDpOrBn0MnAzcDfYYnDP4ypAYtjL0MSw1PG34o5GxUXejKUZeRiFGa4zKja4atzQuN37AtePm +cXFcCneUO22iMplistbkpMlNRSuFlWKYwk6xTlGgOKS4rviRV/KWvA8fy6fzl00501Wm1aavlb2V +TsolyhhlrrJWeUV5W9VCZa6aovJQhao2q3JV+1S3VT+o3pp1MRtlFmWWojZVK9Ud1Z3UndXmaq3a +Qj1LHaeOV69UJ6gT1avUSerV6mT1GvVa9Tr1evUG9UY1qD9Xb1KnqDerU9Vb1GnqdHWGOlOdpc5W +b1VvU+eoc9V56nz1dnWBulC9Q12k3qku9g4O9vYuDaqo2Lu3oiKo1FurKmRTT6Zvp9PitnAq1lpX +dziJthbrOFVd6bw+WpiZFBoTsiIueXUAOIN/PfwEF7JL8kvyctLT9gGvosY3rlMz2sLmyCRmPHES +M2Mtnnlc06qY9E6xL4pKTQpOhe5YZ2ai8g1d5uu9L6xCm5IM8s+SIA+XYD4rivuqsu4LeMKfCt67 +yFxFfS8xXxMVk7cm42hikx+non2+R/mH0zjG3+jL+vTFj4SzOKoc/6NWVbnjm4vwDX938Xk0elOH +0aPNgdnS/AXA1PykJV6zZy2svGcOd4v2X6jgo/ZwM4IGToQRfLdrC2gz2vLeVz+bAx3Ddu1B58yf +3n34aF3pkonmsCBh7oJgXsWCdS/tI9EnzUKfNG3HWTqR+sIFNtkhCmlr5bO3PBYj/gtXbSZ8R4s4 +1c9wvWR/zv89S+TRWWGWyOazQGrMCPXQquhWExpBW1IFDaELxvyLlWnZ5g8nrmPDONVlEzr17AQ2 +h4WPnMT6aieZqDDJ/fOUdTZ8cnwtBn/0fhGAa9ntb86uG5JWrl26fokc9ge/+p+GGcKMPgzTCIfp +qX0KV/NO78do41WzA/LZBoCYhxGc6tNDXhmaT9kOtIimAmbkU/6kceO3g9ig327BYtSVCGDrGTah +668gjVPdlGu2/g3lY6lgwvZ/q7rOwYyVzGDCdD57BUe5L25TI6AKXnVKbrQGG92Q+9vJ/Tdh/+nY +/+p2KGYTAcJqoth0Fu3hSkPYNdoLBepexZLo8Q9fyP7z4/pl9IVC2to9NXwgi8Y1EwM2KeppC4Zp +RaR8ntxo+/E8WcWuiIHzWAv6s24rp7pWhJwckNPFcNDZhrGx97D3b3dxHfWnj3/lXdYwXB65w9/z +NxX1kTNIvfIP+oq1Yz5ymqpX//6jaDut6obJtV3eo5mRj0cXLSRSN3aVWuBEFh1lUyhwp/Ke1QCi +tt8cMXcyZ+WfntlvwcHa53OqyN/c1qeyzlxN7JlV14EOgjvfwAugBpJUPTsREckMTGfWH8S3oZWY +zuxuwsSmh3xG8dAEk52OxfVwHq4eLzsDR6EsqSCZz+93HJWwORe2ZfbWscDawrgJMAAsJTLOExmd ++xU7RRZg9wstkJGHFabLN14g8zZf49vTZokwA6a4+tjDIvBPW1iA87eGgj5Vm9ZS8yiYv1angfmp +UbCWmVdtKPwJ60BXOz6MQ9UoUMiawWzmLexr7XSKdkW7fnNeliLg2l9H5foX4qovRtFJdNilX+gQ +rH51Wa6eo6/mVDOAmetmMnNx5qeH0ov0h9JAu4pzP9fSrjqnBqDzRfrxKPt6NGunm4Hm+MmGvZql +MhXdUvHphr2OXJZtL51xbJPC7s8NehzvbqA3xEvxJeyZfmLxzPL4hvwfaSywa7qL2cvEubCdmrun +cqopvhBJLZlyD7qZWeD8IYOq3L4jHTOoy0U+tlo/xT/TtBo4W7z3NA+j6didG/NcNiecBzoXAfys +in7mKgdFnKN/UCAshegCOAR7JGK4q0QiWvGeRKxcMDdSK7ojuNxJJMJno9i6uOObkZ8tJmKq/5Qd +8awFZkdsCOv1w9Q32hq4/uce+T9yK5X+VoX5f3urojS5eBV/WBGR7pMehKy7yJcxsOOft9m6fdzZ +5VTV2wP7aeck9ZXB1EZI14OpwUzVf6iMxC73o9bmH5CYnKIm+uqR2Hw9EiuouaRV1We7zRiduNTF +NebIpTtZB2q1qidTa7p3HzdtyOAvXV+8uHPxKUYlLie1elUmM/XgPo5B9+Ifl532lB4H/sju/3zZ +aaH+slOAu68rrwKxC5u48sOdqb8uh6jkiPxphDZXvb8AZYReLoYZfvRyd6ghQnxeVChUH8aiZxKD +TFxyockaR9mFjaL9WDDtjLSFR9hQ6vovqv6yEIowt4Fw7m/95I9P/9Dvv77KtV9/let/MbtzFRNk +3IxJhYOnHjdjLoKysxqqR82/y6j5sR41WyFqVtEedheGm48CjwX+XvrLiCUH64GvPBGEjq6z14Ip +Wl8ISQlL470V+Wt2r9n5/ipi38fI8OMK6oeaId/2ygO6hdt1eFdGOZRC/pqdyXzOlqwfuRWpKzYv +hbng6xY4HwO7av7ciVqwq/F77Iu52250TN/GoDtq7YyO6dXaevAD96AoR/wTnfHnbg8j3IFVJ1bX +YroBDY1wD75y3jWoQpIuBqFptK3Djl+nI4tW4+vhABwsLjgB+6EgOWc1v93ucMqGV1xwhmemOzr0 +3t4wPBQWR0DslxgP93H994ScNT8Jp/LL9/ErC7nolTFrIoH3Xll0SksLqOEhZkg1CtXHswvgLCtc +vzH/Ck4cK6/5bw44FvkFo0UtXl74QKtyAEbYvn5067E/LzLWx9OB8k1AytNGqmaN+NZPvvjI5bOR +MYrGuN5sB2rCZKDR9I+kErYR5uqdE1+9Lu8eBkoWzd6lLaOvIZfynuicKkpLKyqC93p7BwV5e+8N +rtCqgovDSkuLi0tLw4qDg8PCgtGCptOOaHKOdDbVMi3G3elM/jsbf8yRPt1cxVxpH9aXeuJPX/xx +pZ6sB+2BEc+TIZ25Io8OdIBvKZv5/oy6Yh+6VN+jMlrcvS8aE0HbyHGsfy9+SyAthjxqqL8g3Q64 +W+cffQnP4IbXcTuYBQGxrn781lDu4La81D0oDyvWd084taRKKORU/76HVN6wfHtCtOPof9/KQfs1 +YcPjMHSg9n05MgyiZROSA1AHNqA8mM6ksxn+egcgxYWdSI+mPwGcZFUY3OlsYC8K4UYhiF05lW7D +u7cVUeKGprc4F8NpRcWsHaKKdqxFIYK8pZEJa6LRlQft9YRl4J3g7CyfXO8pzN6yHSpgb9AR2A0V +2XV1vGpf+rIAn6TooODE3WUH0or2aVUNPgdmz/ZavMCp3O/s2cMVJ81VL1mRydj3MIr7z9CSrbeS +o9TGy4q/g0taQg3KTf5jvKiX40W9HC9s5Xhh+1/Fi//g7Kbncqp/XMgl8oVc5DJaQeQLufX/lwu5 +9fKF3Hr5Qq6tfCHXVr6QmyhfyK2XL+QmyhdybT9eyFWpmOHl8DCKS01xySOLOZX+X/nOXfsrgou9 +tOvTIAXScFAdjBIL8KlLPFHKJxZwY7x8Z4IDP78kuMpc5bs81N+7NKxSTmnWY0qDfkSXGIVPo8Q/ +U5vyC3COPxlSiqnN//bf/wPDaOSsCmVuZHN0cmVhbQplbmRvYmoKMTEgMCBvYmoKICAgMTA4MjkK +ZW5kb2JqCjEyIDAgb2JqCjw8IC9MZW5ndGggMTMgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl +Cj4+CnN0cmVhbQp4nGWWy24jNxBF9/qKXk4WA0tssikBgoFgsvEiD8TJB/BRnBEQy4KsWfjv07eO +MBlMFnaXqKrLU5cUmw+fnn55Op9u08Mf19f2bLdpnM79am+vX6/NpmqfT+fNLkz91G73T/6/vZTL +5mEtfn5/u9nL03m8bo7H6eHP9cu32/V9+vBzf63202aapoffr92up/Pn6cPfn54Zev56ufxjL3a+ +TdvN4+PUbaxyv5bLb+XFpgcv/vjU1+9Pt/ePa9l/GX+9X2wK/nkHUnvt9nYpza7l/Nk2x+32cTqO +8bixc//hu912S00d7Uu5bo6HZc0N2938uDnOcY232/WxOdadx+tjHV8YXzQeGA9r3LPH62NzTMPj +9bHmkzMrZ0Fnkc4yE2uuhfxF+ZnxrPFDhkcMM7WzMyTipJh5Z80b9h6vj5UNnSqdUBmvig/EB9V2 +artiamfVJjSTNBfmWjRX2FK71Th9Ld4X+Yvno79IfzFiU1/oZOlkarNqMz5n9ZipzaqN1EavRT+7 +t+Qk16evxfsiPyg/oZmkudDXor6WRtykyTpmreNC/qL8SH70fPxZ5M8hsBaaN+NDlg8Jn5OvI5qL +NCM9RvWY4EzinMmflZ/QT9JPaCZpRryK8iqiGV2TfRK1TyK1UbVLYd4iNvZJ1j7J9JLVSyYnKyeS +E5UT4YniifgQ3Qc8j/I84nn0dUEnug59RfUV8TbK24R+kn7Ch+Q+0FdSX4m+kvpKcCbfe+gn6c94 +MsuTGYZZDJW4esy8VfNWPKnypLIfqvZDgCeIJ8ATxBPoPfhvhN6Det9vfa2LNAPMwfc/zEHMAX+C +/+5gDmIO8ASvhSeIJ7B2wc8E8mfvEQ9n3xvUzqqd4Z/FP1M7+7rjyfrQiXY/uf53kiWUkq8GSklK +C9WLHM3MnDVzJj/7LwPqLOpMbVZtwcUiFwsuFrlYcLHIxYJbRW4V3Cpyq+BWkVuF1S5a7cJKFq1k +wZUiVwpsRWwFNl+NAk9xHlwpcqXSV1VflZWsfnLDU8VT4al+csNTxVPhqX5qwlDFUGGoYqjMVTVX +Y66muRqeNHnS8KTJk4YnTZ40eJp4GjxNPA2eJp4GTxNPg6eJp+FPkz8Ntia2BlsTW8OfJn8aa9e0 +dg2vmrxq8Dfxd/i7+Dv8Xfwd/u5vM/i7+Dv8Xfwd/i7+Dn8Xf4e5i7nD3MXcYe5i7jB3MXeYu5g7 +zF3MHeYu5g5zF7PBbGI2mE3MBrOJ2WA2MRvMJmaD2cRsMJuYDc9Nnhv8Jn6D38Rv8Jv4DX4Tv8Fv +4jf4TfwGv4nf4DfxD/iH+Af8Q/wD/iH+Af8Q/4B/iH/AP8Q/4B/iH/AP8Q/4h/gH/EP8A/4h/gH/ +EP+Af4h/wD/EP+Af4h/w6+503Hv+zk/xwz0W5971d36eHO6x+jp47c7fPHsj9rfoPZb+3pmD9v93 +J1n44UpGkm+Uw86P5Z2L3l/HauwwE3tOJNZk+3vsk3G186vLnmuVvw72iViG7g8e++tmX4ll4uEe +l+9BdZ3UvffbPbV9vV7XK6pfjv1uqlvp6Wzf7s+X14uq/O9f/gio4gplbmRzdHJlYW0KZW5kb2Jq +CjEzIDAgb2JqCiAgIDExNjkKZW5kb2JqCjE0IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv +cgogICAvRm9udE5hbWUgL1JLSUFUTStTV0lGVERBWTNCb2xkCiAgIC9Gb250RmFtaWx5IChTV0lG +VERBWTMpCiAgIC9GbGFncyA0CiAgIC9Gb250QkJveCBbIC0zOTQgLTExODMgMTYzNSA5MzggXQog +ICAvSXRhbGljQW5nbGUgMAogICAvQXNjZW50IDc3MAogICAvRGVzY2VudCAtNDMwCiAgIC9DYXBI +ZWlnaHQgOTM4CiAgIC9TdGVtViA4MAogICAvU3RlbUggODAKICAgL0ZvbnRGaWxlMyAxMCAwIFIK +Pj4KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL0ZvbnQKICAgL1N1YnR5cGUgL1R5cGUxCiAgIC9C +YXNlRm9udCAvUktJQVRNK1NXSUZUREFZM0JvbGQKICAgL0ZpcnN0Q2hhciAzMgogICAvTGFzdENo +YXIgMjU1CiAgIC9Gb250RGVzY3JpcHRvciAxNCAwIFIKICAgL0VuY29kaW5nIC9XaW5BbnNpRW5j +b2RpbmcKICAgL1dpZHRocyBbIDI2MCAyODYgMzI2IDQzNyA0NzUgOTE3IDcwMCAxNzIgMzEwIDMx +MCA0NDMgNDYwIDI1OSAzMDAgMjU5IDI4NiA1NzYgNDA2IDUwMCA0NDYgNTcwIDQzOSA1MTYgNDAw +IDUxOCA0OTYgMjU5IDI1OSAzMjAgNDYwIDMyMCA0MzAgNzQwIDY3MiA2NDEgNjcxIDc0MCA1ODkg +NTE0IDcwNSA3MzYgMzgwIDM2OCA2NjkgNTYyIDkxMCA3MDMgNzQzIDU1OSA3NDMgNjMwIDUxMCA1 +NTIgNjg4IDY0NiA5NTIgNjM5IDU5MyA1NzAgMzMwIDI4NiAzMzAgNDgwIDUwMCA0MDAgNDg0IDU1 +NiA0MzMgNTQwIDQ0OCAzNTMgNDkyIDYwNSAzMTQgMzE4IDU1NSAzMjAgODYzIDU5MSA1MTggNTY1 +IDU2NSA0MTkgNDMwIDM4NCA1NzAgNDg2IDc1MCA0OTAgNDYxIDQzNSAzMTAgMjA0IDMxMCA0NjAg +MCA2MjMgMCAxODAgMCA0MzAgMTAwMCA0NjAgNDYwIDQwMCAxMzAwIDUxMCAyOTIgODcwIDAgNTcw +IDAgMCAxODAgMTgwIDQzMCA0MzAgMCA1MDAgOTQwIDQwMCAwIDQzMCAyOTIgNzU0IDAgNDM1IDU5 +MyAwIDI4NiA0NTMgNDU0IDAgNTg4IDIwNCA0NzQgNDAwIDcyMSAzODQgNDgwIDQ5NCAwIDcyMSA0 +NDggMjgyIDQ2MCA0MTUgMzgzIDQwMCA1NzEgNTIzIDIzMCA0MDAgMzUyIDM5MyA0ODAgODQwIDg0 +MCA4NDAgNDMwIDY3MiA2NzIgNjcyIDY3MiA2NzIgNjcyIDg1NSA2NzEgNTg5IDU4OSA1ODkgNTg5 +IDM4MCAzODAgMzgwIDM4MCA3NDAgNzAzIDc0MyA3NDMgNzQzIDc0MyA3NDMgNDYwIDc0MyA2ODgg +Njg4IDY4OCA2ODggNTkzIDU2OCA1OTAgNDg0IDQ4NCA0ODQgNDg0IDQ4NCA0ODQgNjg0IDQzMyA0 +NDggNDQ4IDQ0OCA0NDggMzE4IDMxOCAzMTggMzE4IDU0MSA1OTEgNTE4IDUxOCA1MTggNTE4IDUx +OCA0NjAgNTE4IDU3MCA1NzAgNTcwIDU3MCA0NjEgNTY1IDQ2MSBdCiAgICAvVG9Vbmljb2RlIDEy +IDAgUgo+PgplbmRvYmoKMTUgMCBvYmoKPDwgL0xlbmd0aCAxNiAwIFIKICAgL0ZpbHRlciAvRmxh +dGVEZWNvZGUKICAgL1N1YnR5cGUgL0NJREZvbnRUeXBlMEMKPj4Kc3RyZWFtCnicnXoHXFRH1/dS +7u7lLrsKchWNsmpEjb1hizHYsCsBCyAgKigoXTqogKjoSRBRilJFLChYsGAXe+wt0WhMjKlvuqZ4 +7jqL+51715Z8yfM+38fvt7sz8z9n2qkzg5XK1lZlZWWl954+1mPKyGG+fYdHhQerrGxVKpUVfdyl +N6TWYO8iNVFJbawkF2vJYCM52ZpcWrNZrdVzng7lMN6+fRuVqo2vfQf6Ue2xd5V/aprI34ccVJyV +lVrfddDwYcFRs0PGBodExoXFJY+Iik6ODZsXGte285y32vbp1dutW9sFIeEJYZHdunV7OZO28lRe +1lQqa5rRAxtlWqqHqodytb2qi2qD6rrqrupL1Y8qo9Vyq3yrUqstVjut6q3M1rx1kvVR689tBtss +tllns92mweZj2z6252zv2H5ri5yGa8F15Ppzo7gALp5byv2qtlE7qjuq3dRj1T7qfE2GpkCzRVOv +uav5nrfn2/Du/CQ+hs/gc3m087abbRdrl2G3xq7Cbrfd78JgYZwwRQgRlgrrhCrhiHBD66htp+2j +HaZ9TxukjdIu1uZoa7VXtT9pTfbO9p3sR9lPtZ9rf17XQzdK56uL0i3VlesO6S7q7ul+0El6O31L +/Vv6gfrR+mn6EH2cPku/Vl+pr9Nf0H+hf9RE1cShSdsmvZu4N5naZH6TjCYFTa419W4a3DSu6aqm +65tua1rf9HzTOw7tHbo5uDkMdZjoMNUh0GGeQ7RDssMKhwKHK47Wjh6ORY4/Of7p+KyZXTPHZm2b +dWk2v1las+XNcpvtbfaxk52To1Nrp5lOFU43nB6ITUV3MUBcJ/4s/imam09uvqj5582lFk4t+rSY +1SKvRXGLnS1utnjYwuzcxtndeZZzvPNK5wrneue7zt+05Fp2bNmn5dSWoS3jW2a3LGlZ3fJYy/ut +7Ft1bzWolV+rVa2qW51sdQ+OSb2PWR07hg3HbI41lzpI+aYO6mOmOaLUGxtMvTX678/gz+JyQf8N +vrdcrLid/9UH+B4/C1ZO5sxm1jfCbI5W3zSbT11eazbXGntEhvK5iRw+wW/FdmyHGuZtSC7N4Esz +sPXmVZsnf5C4i7uLxWLJg9TC0DS2H7jR4B85azZfGstt31DzwVng9wOqs58Ap8cSvIebRNZgis6L +NTaHIuwcnBvnYcoCPCDNgo0slSyjC5T32Z8D6GQilqxYTt8b10ktxDJBn4+fYg9xs6CfjSMkvVgu +6DFPaieWCImm7mKp3Jx6QzSr2s9oMJt/qnU3qxyr3M3mr7wawI9nmremM2eXeRqchD1vYlcDXJ93 +YMJGs/n7b4lQU08sD1s2mFU2Y9wj36+v+vocPIR7vsfehhEwO3HqXH5DLFdXUpJbAwdgVyxMgOGR +M4bO4leHcQfBrGq16rLZ/NRqgFnVOr6f2fzrswu8/jTuxTyxQghHa3GjoA88xlLESkFfjSNwq7hJ +0LfbjI/EKkG/A0/hl2JXQR+CScaF4sGNE5jWAENXhSSGpaYuWREPgRBzEVALn6yuK68tLi7K2Qh8 +oqmFiOqbX2BbbDfw9Aim9hjA2rJ2971uGfRdMdJYKEYIetbhGD4UsTnaHvrZAAcX7gksMZu/+G6c +WaU9Mctsvu18gJbrXj4F+PVfYSfIv5JZyIbCfBZclModoFWJnp+bzeaPp5lVzrvam81Pumyn9XU0 +mM1/XHjPrLK/+5B2uf8uiOQ9o0OZvYu+I74pFYoVm4vzK4GvLY4Z7Z8QGTlv4YFvDYCdztb8cIhf +vI1jWn+m7gmsGe96Yuo3X145de/K3EPuLnNhQUpCEq9nYzcYPcX8FAwEzp9xke8NYm34y5HYVWqT +WsaWkg71w8XSVbFm/ak9cJY/HVI7sHegj48LMD1OSYJB/MzY5OA5URuPukD9tq0Hq/iUMs4vcUAg +TOZHNUR/9+PZ4xdcAO2Z7xr4id+xfmPt9or42S4wPzM0IpGnFWRLf4gJMakZccCHpVZcO1yxbduu +TSG9DMA6TQvpFsAXRXKoPYxW3wE24x9PP9m736QpQ8bunX3bpQa2llSU8XrSrzhjgThPuMveFbsJ +W01viN0F/UrUSyepEe3YIHGMUM8yxXhBpn1gPCwmCZGs/+u0ydI31JjPer1GOlH6tPm5UnVACUuW +/hwLLNz0eGwCJOMkgNJxG9FNSsR3TMmJc7kxQf5B4AVT94ddhX2wq3RTMZ9RxiVnLloRDfyCuM11 +53ZdQQeDqRuGi3h2NzurphF34QxxrDATM8VJ4JPoo+j73rKNa/cDf7kyxN0QqolYEbTSY9G7abET +IBh8d3jehiNwrmr7GT7fg4YMVYY8rAy57y9DhkH4Zqgjderx3u+kNaYOZlXbh2RoI2zum1VvHLjC +f2pWtRPTV5WErs7YBxjKodWkuh4u8oInPbUTwwSmanwk9hD00/CYsR/V32RLxXHKhrQzbhajBNQ0 +RlvwXOm6XNcyGwsB/mjcJc4RzjUeseB+0j2qXmSTnvO/aTwmJgttnwkWOE/6H6p2YKUKnId/KrCp +W+MzsaeAXtJtsRe1zzfaGMPFFMH0pWmTOF6QhkqZ4gSZfideExcKuKB5nKA/WU/7ybp8OelLl4tQ +v3HnHh680L1iVYlf3pKbILmdAtgzBQBbsLGpkHxzCfT3Am5MPKRiU4AOXPzakLXhwLP2A7uy9ga8 +zuzEyJjYdH/gA713ogs2233immE/VGdVZfD63zBU0bcaFiX2FrDCto/sS1oq6vYHCxQnCkRyS1Gz +YWzuayRZipatZFMtJCXKZiWxGa+RTFR2rIGNU0ik2OaT3v+P+rUA4mRhn9u88+J2ni2iDX3Zl9kq +sHGLWSW07UEu2oFfRk63Sm1W6UvyzSr+6S1CAsgR27kb+axSLjJ97opI4PtPP4kGAy6HtWe5x2MP +9mPanv1ZO9b8cg/s5GJWWQ1YRXplNbCXmfKYZ3LpKJW4H83mSz6rzOa7VZ+ZzaRk5MOWimA2X73m ++h9nbVb1Si0yq1zfJD/X/cN2ZtXbd01mVef78bzZ/Hb6VurowU2au03T+WbVzM59KLzMpBl3vHPV +rBrqyANft2lBD4NXJkd7+ZGiOmwi2/7aZi5T9ItxbL28mxj1Qn/DGweLfQX9GnI+sv7+0kGcJOAI +V3GywBpNQ8VUAY9Kq0VPhaW9Isc/GnMtHCsVES5h7/07y3MjwH6Nyyw8XopMDzCP/zDM2Dmk4ace +WBhCpXVimrCDWf8rQw7+oSyFTR4k9qO6Fs8Yr1B96xjxPRk+ZXQUIfHjeHhrEXiTlt8AMPUdFguJ +uBagfHQZYCXmAgesZPSLxmFlIA26TGYyDuDnjzdCOaPWRO4a9cFyqekaNXE4gVbBVCwXVRp5VFup +QgRT/JhY8oup5BenFgMWc1v2b6s+DPyBrek9yI/He8UTmkCoJ6EfcI8CG9xcBsL8gLkzeBz77Z5e +2ELz0ipXgGyUnL4dfmr8RIwWOrNI0Y0i6xA8arShelf2jphAsfyBYoE4gExQgRsszn4wG6rA6K2I +7TSZn4W7nyK3c8xNhtuierEYOCsmmEL95KPh1+AYHHyhn1lJ2eS1584qPXOurAE7G6B8Bm3MSWVD +CmlDPooH0xFOz9yxBznHtsJlliWykYsh+coSYL8kTeH+6359i+RltrYoiw15ActMo6SR8hwxXvqU +1Le/wL6WdsgQdpR2Sr+K3gIbzSaIUwR23dRe9BI8pc+oTc8EHGdR7iGsKXHJPfWyeOcR7uIiYh8v +tZV1jL1NqjFAwLPSCXGgoL+OPymtl4xzxKkCdmUXxGmC/iKNPkxkw5dC8qVFtKxRsnyTSYJ+xRzq +pDdEiKtOZu3Z29iDRWAbAgIPsP4440/UXa2ASk5/B9OVUOLJcsVBNJnBGPa0txxaMtg8cbpA+M/K +sDY0GQs+T6l70DRkWPIwjpTr/r1lOEZSKRGAPfCzMF+TVLRpozBNRn2xDr+jKltO+bIC35QcRNiZ +sZo5TmDNvCFs3XJ0usQ1YKUyVnPcLdlZcJspzHaGgnOnOSbi7zI/RkidLHHwVOMhcbCA57GT+LZw +T/pBHCLo/8BflKDI/Ji/6KNQOytTT/niH2i/U6BWUoyFFE0WN3Wy8dY/EJ+2uCtflqBQO+MKaTSV +2DA8T70Qe71s1Qk3U8F0yj2OzJYCWvmESpDmfwB42bQAPDkYtyopMyw9LXXFQkikc0NaLp+2LPNt +rnRZybIa4D9D/if0MYC0/UYl6fNk0ueLcWByZ9ekBeRFJVtprPjcMgM0W/bXVu9/bsWsRvPfdY3R +GsW+WfflIhvxwiwU/5Ci+Ac6k+RjqcV67dgc8R0htFElDpXT8j7PI+hM0VfI2yP60ZLzJV4x5Hzm +9zpl6fNAOu11Sv+nanGxwOIL6DubFb9O/9jY+yWUxgpfcXXAZxZRv8feF98V9GNwr0W6BpqFv0wg +OSki7GFsbsFD5WqWFGlBKcwrAvVkWyxwtkWGLixZJtiEJy3dr2ncKboLem9audy9Ky0nQIbXKTYb +0djDgkZbLFY3yoJOYEHifGE0FljQTkr1gVGU0Ss4R6mio/GAOEzQu2IbpX7FuFQMlOEdysy82TYL ++oXRXV5HW/aGAkuT8Kq4hx3SyNGBwyzcbSH7iGxqD4t73jyAMiyixkAJFG+ca7oiDhf0D6R+ijNm +i5m7OFPGscgi0XLTVYUAhymy3MqGWXDJRhEj9jOdteA1igSHsIHPcWvjz2KM8Mt7YqxwwXTcQrPD +6PyijY1ivZ9TTn9NzNipUW2ZkOo1CfekzbfQTt0u9ov4r/Knfcc+Pszfxflyb1+gv+z9hj33fsC1 +q5tx3+UuHD20+whfOPi/TL69VHLyPUxOvo/LyfcJOfk+9bfk+/eXPraIi54VGkEJ5+zYis8Nemmu +lG7x5wOZXhxBqymRWlq0o2dXMUjQP8FTFvxDwkcKVaRRowR9LIJC1L3RTkyU9/AzRf8+bDwoegh6 +H9yoqN9q04/iLBlNsQSfpMalFniokqngu6YDMs7elFoY+4rJuYk584EfxPTubLQBTI5KNCggax5S +DNJwDi6/vym/tqAoP2cTlMOh5A3L+Q1rODaOItqetzWWcE7RKIbiGsUhN/RWshsqvG90kf2aGwZY +jMZ6HH3r3X5QVIea45TJUmEMFUbLBX9Fa6jgqkyUCjNe6QjVtr6mBXpa3VvkME2/Jao/loP2y/TH +Qw7ouJhSoiMer7IfTonynP5/sAbPiCyF7ciLlcJe3JiwO4ALsBA2soGYikte3piMt9yYfCN1x5Nk +OAs0QWkQx2EnPCLe3kyJ0mRKgOyz/GJ94sIWpc0Edwj9A3AyoMOaI1XHK2s3ra8HPsb0h9hF0F/C +1UtE7HDvAbY0wOXQwz5beHSA57c804FjfdzcWBfW+ZdpaGs4hJJ4OqZoBgwBj6XzF85PSEpZGgYj +IPi4cnNRfvZWPq8/gWuNHuKzbnuedtOMYwfEZVs41ipyeGfozLNeKHqjNfZ/8gjbYi9mf4LZuGTM +4W4f85BvQ/olhURHJiQlZs2iKY+4pfRZdObBIV7PJh1Ef7Gz8KpQjqGiFFRvClLr2bnvacAM2Vnd +UgrMvznV2DrU4ClKlvStbRtac0fwkvimkMruiB0EU3O886pi/3qli/T0ZUVqgU9FV+qp7KFxlOjP +QmoXPcFJSzdx+qeOtlJ2vSlbrTelYKqxRIwkyaulM5grmqZmk4d2iaihY4En0mfHLuaKLaQp2RSE +1HvlaU/NYR2YS/V8Orp6MvosmIeurIVpSg5RbDG2wXki4a3/houmWqCOW/+tY1Hu9TDmiFnKDI5h +hLhMKZ3A7qLJLxsN6EQsI5gH0odY2lIq5ZvNmfJwoSj55VDMcaKRRqAHow+N1JbpTL7yTNQ4V9oi +vuCsrmHUk+SXDfUm32ySno7Dzmy8GDEfqQeTXw7MlHxzyNPrdsyTe7Ms1kekZq+18nJqwmk547PK +OXYfqduJbHxeopQP1J3XUnldlnX40Dqybj5fwhkSn2lkdmKI5JPNTbM1+WSXh0gjae6zborYC3u+ +vhWW8fqL0sic8j0mnxyuwVbyyUncYxqZw0mzRoqsF+v5+o4S/TTpSXOWaXQeCyy90Zk7u1vEUcr1 +SiKBV42LKLg0eihm/MxVMeNSMtkhZfC0K94Eahvyok0246ddZTNmjhizSZS2av7RPa3/gvurWzNt +lROchRlh6YszsuUEJ6BUSXAW9edKl5dnKwmO/jaONuhj9uMCsSOpoj8d4IeLbwn679EkPRPrwzd5 +utSW1WymmLB7QdU8CIe4zKhkviCJKy/Iz6mAUihOhTgIWZQ2I4pfm8qdrIwNCwiKG2qI1qDthf2X +Dew02yxfEn+PhcZYkc0q1NTSgWl2OnCZV8XSJA0dxP0L0jAKYDubQlGJnZepMU1a8YX44Iszj38d +d3Cw4V2Y9E78HL4klqs+VnP0GPB3tk2c7J86x9/AeHLbuWwc8AP6e7l2uhR433AHLtzduJdPqeIi +fMP8fIF/N+rC+cPFew8bkIdSOuURsX4Z/klpIbti6lsaLzUlNWFfAO7CRk4fc6xEXJOynfwgPkFn +9vgUrCtiQ6QhUUCY1FPqLS4rCQfmxJ4wZ3w8BTIX4xDTkK2E+p5fJVZlF+YDruZQfXD7jeu7gjq5 +ACs4/KJRP/M0Hdw1M0cwKxe9r2QvDRVjc5ZkAFvNMXVg+CiPeQd+dQEs8H/RqK/3Rg419beQGGKk +3lghrhBkabUnad217ShIGmyuNOERiZLTDiav7RmU33lxbDf75e80xB9EhVR0t7DUyFvgbBKJxVkS +ucds4etotYw6KqgjoayM7aEOUW0r60mvvc1xRT1bocZQ/EVkoawP0mfLLrLyJjgc9dxrJNurRaLq +w+gTTcbLmrDhjAikAmm49K2YLbC7ts+/qM14mc49bana/PkXteHw9dSEd/Huqx+ZNNtb4ab6yx99 +109ZinhZDcTVCX/6GZvySaUcs2M6NtzkBKalvL4rupLpjXuWdllN1FSkViSQMncdX1bKvYVNGbFS +DzLtReoOpKVsuOTE7FDHJyVzP7OmlLb+BCYLwavOLGU1AYzwt1hTviyZQ+JC4qZOKNCM/FWe3lMf +9SdFUMnak9awkTjoZReEU/lZGrav1Awtgqc+Cj6XeJ6msfZxmk8Ww7Pnba/xPK/4qIcuhjiUOx2E +7xDPFeMcNWDAH/vOlfLLK7i+S1ibAcCm8y9g/JJgddjOWcX7i2t3UpHHr8cykwbcFs/zzOQTNecy +i+aBm0IveytfDXFjmwFfLeFzKzjP0vaU7AXwxjkaIlhCBGOfpV1Ry2Xq3EjEOJ21edC3kF+ewJ1L +/mM2sAC+8RUxo9GZujZ0f+qs1LBQKvLs6ytIoz8s2nVuHV+u8Vy3eBc85F/QN9JiWED72Z7JfG4C +91UhtnlAI9Cezj6KVSK2NvU9tJ61lFyxpdQhYD1t0mxKajaJrLXUN2ARtjS5spamDocWcfpXT6j2 +8ktoO/mJNMpxSaH0TiEGFG5br2YpoFGQZlK2k5QiltkL79vrVSvlZ81mKieVqBqs8lIFqkJUc1UR +qmRVvuqxVSur9lYRVu9blVmdtfrEuot1pPVK653WF6x/tLG36WzjZjPOJt4m3+aObbztJtvPuDe4 +YZw3t4hbyV1X26vHq7PU69WfqH9QmzS8ZoImWJOgKdTs1FzTfMt34d15H96Xz7PT2420y7A7aPel +3Vd2f9o9sUM7yc4sqASd0F8YIAwUpgmzhYVCqbBLOCl8r7XWDtVO1V7X/mZvY9/BPsd+l/11+/v2 +n9l/rrPX6XR6XTtdP52nLkX3vu4DXY5utS5Xt0aXp1urW6fL1xXoCnVFuvW6DbpiXYmuVFemK9ed +032uM+r76Yfpp+h366UmYpMZTfybBDQJDI6ICA6uDq+r2769ri68Otig1WqPV0/rZoCJmTHJ0Slp +WUvngw+ENcAPcKFwS+mWkg1r8yj0aNH21k20R4feB0Yx25GjmD1z+HrmDYOWmRs1NYloNmo4rWRf +b7JXa7U49xKbq9ZSIA3dn4bpxlBOi92+Qz3GYRrjb3Vn3boTfxxLQ2HY9wbt3o33L8J9/pPZdI5g +dpOHDCEv7I6lvkAWPmreHM9JgXvvucAnlbUX6vjEbdyE8D4jYRDf4YYvOS/He3d/JB/8Dtu8DdCV +P7N138Hj1fNGuoDvkim+EbyWRfzlyeQckvnBBeYxOZHallObt/K2wmnZRPgWKzntj3BzS+0Gfi3a +T81J6cRFp4dl+QHPWrk9xqk45vRP2NZwFE6lbVnC5/c6DGvQiQvbMLm0L5FEMVtKbaazBWjLVDjT +oMUiNcajIyWe0ej7zp9sh4Gtfn4QGBrLaS+rccy54cyLxQ0exbobRqm1OP1lUu8Jyt2pTAmJUgQU +oNPs3Kg+LB5oLzvARu89ANg9BOK9WQdqWrw8MnsezcGp32//2zSjmc3zadrQNIMMX8H1kjO1POCc +Ixsp4K4ESH4Qz2mfD/9/Xdi+fl/LDXt5Lylf1F6LB5YtX9RitnJTq/1IRope3FgOl9moVj687G/Q +TQ4mLGZWw8fzhSkcclduow2ghteelomWEdEtmX+EzP8B8Y8n/utlUMVGAsQeSWTjWdLMGRjNbmAX +EmjAfpaJh5+P8PK6VNnGuVCBTgG5cX1YEu2ZNP8DTQM6sDHw9wst0oZr0oJpzAF/NBVx2r9eVMWy +ofeI+9dPaB/lo5VD8sz5PuFhwQtHQCcYKM9cPlttPFhzfHvtvspbsumEYDPKT2Tl73uXObMQiqmO +ivr3fBudDdpb6hubg4cwm5CZ7Q2Qjv7sOralhcw6yEYjcKdLvj4CaMv/6n2ctXZhu18/Sq6hyY4t +5bQJv/pn57I23JHUsxk3AfvCnfvwCNDKbK73TDerek9oMJuzd1Gp/153s3mr0d2s6jyDSg/UDWbV +G1UN8CFcP7zjLByEHZnlWXxpj8OkhE252DWeRUOBtYB3h0MvaGdWvRtEHZ3/hZgSyon9ggN1NNNV +ZTbfekSdN/+USl81SYcJMHpGyFiYBWF5geW0/k5Q3m3/B8vRJRGmLzfpYXpuIixnLvtXVvxAGJiO +DYvlSDXKNbJmsN7TArt3mnoa3yS7fvKhLEWgvb9JyvUnx0ZceRtH4YBLP6Ebwb9dlmEvBea0E4C5 +mCYyF2ni2TKoYDkk18upOMtkPAkc4JvSlPcN+KZp6kmKQxJ+VEokgbLokyipmkDmKPMMp4ZTiZR+ +5DItrqmTm1Ko6cNUHGdSXZZtby2lhB9oFF0stKjKVsBb0qVFW9jXysIWsXaHV5Z+j6nAbpguFkZJ +U6AMXQJyOe3ouZCA7ZiwjdzM//OLKwzBoZtWlfitXvIh4JTnD6bayZo077DwBRAJSeWwB7aZVdab +t5hVBumeWeXq52dW6TQdzSrnTSqzii8ksbUPoJJNqHt1Dq+thE0rNizjK9zr87J+55LzZq+dTe7B +gdmNZHTI/58xTwxH4GbhgUP84hIuYXFIVhDwg32vUXpkf6j+PDn+1186azX/+la5T/PXl03ti4eW +xg4vX0c5bX2Z8o7WHSAMV/3j099JOFe5tervD4VoX37kkkHbUOg/YUh6pN+M5AOX7hTsPGbQfjnm +SMeO745z63d1xqNHdy5+5aJFbkNufUY+s5vJvZyD6dH/97uRFqT2r15dlAupbCLktHJYfT3MumgV +GpMNeblkZv3Sy91Ba0A7XtJotM/n8tobBxg70Sz/9XmDuQLEcX/hkwcf/5xvZOrrt96vr+7Vffr/ +srrzdcOZltklTBg0Oehj1KJd1YXPSHau/fsxV+b2u/dv6Prwa3RFN9eT7SiJeLUTypDr5Ku5EsA1 +3OZ9m9fthmooXbYpi069Bd9zKbkpqyNhCsz1XzCdArR2+pSRBhhxJPThXLPqna3kYL5JJrfi5EMO +5rflDRAKAeGJ3vSTtC5pHb/o4xkr1jAVtzPj6NJjgM3h5Cm4B3d9NvetM5svhpOKtzhOjJ+upS6a +DWuAnbCrqvwo1EJ51oalfNmIfTkrf+Mi1gXlB5Bj7hoMA2NgdjykXqW4VsP13BZ9zuUEnC7dXcMv +ruCSFicvSwA+eHHlaQOWo/UeZo16jfblfelfb2Wh16vHfvz4Hy5VF1Z8btBOBqZiNT2w6FAxBdsI +CrYNi7CP6a0DgDyeQh07RaUekuvFUq6UDU7WnErryjaSRD0Ak/BZ5ha2CqYoToavX1FyjwIeS2KN +eVH4BxQjH0RORhtRFVtdXVVVXR1bFRERGxvhQhkeZWQH5YxM68q6b4vDdihABaddE8Ndz7u0F47D +vsXl7iX87pMLy5YkeQ/JT+Z2ZxYnw0KIT4mZtZQnfubHjq5Nwh8ATrD9FN7QE9ijCrhVAdKbnNa0 +svFpXaK00viUHKT1uMoqOms7UKBzqKA0JzJhybIkcmbh24MgCoKX+PjwZfHctorCNWVQB9vDD8BW +qCs8fpzX1qyNmh+SmRQekb51x868yhqD9mTITk/PObN9p+4OPXduX90JF+1jVqkeakkkuH9Orli2 +q+ynV13W/DW9wi1otVv9jx6zQfaYDbLHdJc9pvu/ecx/MPfxxZw2IyujO1exvGRlDZwGs6qjkThG +zadehmiotC6/gcf+skRJ4INJ4GfTOrGijlhY/0IDTizCISZXLsnPbH56mfT/0Xr6etxX/je2ufT1 +uDjdbP66J7V9G0wl6TrlKWkwtyCNZjQNwovjd/Ex6VzF5PrAq3AV6g9WnOdjCrj4eeGp00jHmfXl +uFgkWSDJJKGK046awxVH58VCPEQuT06O5QuSudO7dtbDOdiaXplRyGtH3gz9Ezt99snHLnDDbP6h +K0X2Lt1oHgUfyTH+VgPPxK3cgrzUdbAeCnPzt27iYwq5OXFBPmSjgZVxpxbxO5aiLprbm1mWChH8 +zNg5Xd/1rz7uAvuKC47U8AvWcgkZAxfABF57Yy+XuiWrCjbCttzS0io+vZTznhc6EzwhqiAuf8mr +Df8336kNYh47l3yHfbMoEGu1s6JDpxtg8m6vu3P4gnLOrzqRshtTOsmkpU065EHOB3n83u1VdbUL +N8+VDz5ZiTiRja/Zzjpga8lrKdRz2rxyNhHHzw/HDqy1yWstUKw4W4J6k6YO8Mun70Tks4ONx/vg +4bQ81moMpw2NiVwWSeelGXu9SMVnp08L4otjuJ2bt63ZRmZ1ZM4ZUvF9BQ0HeG1wdQRFg2o6dG2n +6BAerJjl3/+ulo1U/hEwMygxLCFpyfIoGANxlqvvwgPltRVlRau3ygll+wdfYxfs1e5kb9Z+UD/W +hfX63fsbg/ZGOWkUud7kOwnAfnSTdXQb6ejbpKP7a1K9DDB4Sn/m2pZfswBvQwk6JeRGB7NBwN2/ +8Msn8A1cDzo4EMZBQKK3JTEpKVlTS6OZ3tmk+fI4SO8mkF3titGwA6bu6xKkUIAPTV1kU3v5z5Xz +6ydtnlk6evUQ4DehB86EwvtZRSwdAtkX+ZncXflJ6iypsSlRtqvBpFI/ZZOVuB6j0g8ryVR0wwn9 +KlEFQXyHEZNZTxftlspN+TuAP75vpmv36GAv/5nnsY0BcD6ZvTVqP+RTt3DMbSJzZxTOInnW+6I7 +tkbH29+g3S++HzEbFy+YmxCxgNfmp1CuzHmwsR6srxsbw9+NxgijdWoZO0sLiI5btHwB8D6zax9/ +v7HuzOG6yYwGYfPbs2ZMO4kvjubQ7QL2x16AkTz2nnCbtWA6997MrvP5CY9czsCW4uodspPU/h8t +ahH9CmVuZHN0cmVhbQplbmRvYmoKMTYgMCBvYmoKICAgODc5MgplbmRvYmoKMTcgMCBvYmoKPDwg +L0xlbmd0aCAxOCAwIFIKICAgL0ZpbHRlciAvRmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnicbdfLbttG +FIDhvZ6Cy3QRiHPmSsAwUKQbL3pB3T7A3OgKqCWBlhd++1Lzn6ZB0AAJ8EfikN/wMuLxy9NPT+fT +bTr+tl3qc79N6+nctv52ed9qn0p/OZ0PRqZ2qjet8W99zdfDcd/4+ePt1l+fzuvl8PAwHX/fP3y7 +bR/Tpx/bpfQfDtM0HX/dWt9O55fp059fnvmv5/fr9e/+2s+3aT48Pk6tr/twP+frL/m1T8ex8een +tn9+un183jf77xt/fFz7JKMNh1Qvrb9dc+1bPr/0w8O8/3mcHtb9z+Ohn9t3n5t5Zruy1r/yNr5v +9u+LmPw4SvaabZ0py2eGcveRo9Xy1EIFSqhI6SiJstRCOSpTnipUoCoVqUYlqt+PbI66h5ViTDNT +jGkMxZhGKMY0lmJM4yhE5u7bx2IPJlDYTaTQmkThMwulx5IpPZZC6bFUSo+lUXosndJjWSnOkcxU +oQxVKaEaZalOOWql8Bl8gk/PtOAz+ASfwSf4DD7BZ/AJPoNP8Bl8gs/gE3wGn+DTa9DiM/gsPoPP +4jP4LD6Dz+Iz+Cw+wWfxCT6LT/BZfILP4hN8Fp/gs/gEn8Un+Cw+wWfxCT6LT/A5fILP4RN8Dp/g +c/gEn8Mn+Bw+vcccPr03HT69Gx0+vf8cPr3/HD69/xw+vf8cPr3/HD69/xw+vfsdPovP47P4PD6L +z+Oz+Dw+i8/js/g8PofP43P4PD6Hz+Nz+Dw+h8/jc/g8PofP43P4PD6Hz+Nz+Dw+hy/gc/gCPocv +4HP4Aj6HL+BzPJn1Cfw/T+SA3CMPyD3ygNyjC8g9uoDcowvIPbqA3KMLyD26gNyrDrlXHXKPLiL3 +6CJyjy4i95y9iDxwhiLywBmK+AKGiC9giPgChogvYIj4AoaIL2CI+AKGiC9giPiCGvAFNeALGBK+ +gCHh0zUm4Yuch4Qv4kv4Ir6ET1ejhE9Xo4RPV6OET1ejhE/Xn4QvIkr4IqKELyJK+KIe9fCJ3rVp ++KSw3TJTbLcMn1S+uQjF3hdLsffFUTrK8EnjPCyB0u0ipdslirlehs9m5nPJFHO2DJ8tOubw2aqf +DZ9tzODCyq/r1sLKr+tWZuXXdSuz8us6kln5dXXIrPz67M6s/Pr0zJ7SUQLFFZLjKH265LtPzMKx +5IXS7TKl3yyjCjOR6yj9lZUbpd/sFFdIXikMZaY4f2X4TGOUIhR7L/xy018axVHYy/CJrj9l+ETn +rESKuS6J0m8ulO49U8xLKYypx1IpZrc0inNbOsX1UlaK66UOn+haUfllqs/uKhRjVnz6tK749Gld +8QWOpeLTp03Fp0+biq/3b5/I4r5/IFfgnemrwFcdHvjKpVMH3C5MWG2UcjrFJVBXiulrM8Ue2oD/ +e6M0odhDsxSnqzmKG6V5CmoLFNQWKS6Iligmsy0Uk9kyxWS2QnGCGr6Mr+HL+Bq+jK8NX+yM2Wdq ++Xai768n93epr+8+9X3b9tee8cI13nfubzqnc//6Tna9XO9bjb//AJ+bDlkKZW5kc3RyZWFtCmVu +ZG9iagoxOCAwIG9iagogICAxMTM1CmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udERlc2Ny +aXB0b3IKICAgL0ZvbnROYW1lIC9QR0RSSVkrU1dJRlREQVkzQm9sZAogICAvRm9udEZhbWlseSAo +U1dJRlREQVkzKQogICAvRmxhZ3MgNAogICAvRm9udEJCb3ggWyAtMzk0IC0xMTgzIDE2MzUgOTM4 +IF0KICAgL0l0YWxpY0FuZ2xlIDAKICAgL0FzY2VudCA3NzAKICAgL0Rlc2NlbnQgLTQzMAogICAv +Q2FwSGVpZ2h0IDkzOAogICAvU3RlbVYgODAKICAgL1N0ZW1IIDgwCiAgIC9Gb250RmlsZTMgMTUg +MCBSCj4+CmVuZG9iagoyMCAwIG9iago8PCAvVHlwZSAvRm9udAogICAvU3VidHlwZSAvQ0lERm9u +dFR5cGUwCiAgIC9CYXNlRm9udCAvUEdEUklZK1NXSUZUREFZM0JvbGQKICAgL0NJRFN5c3RlbUlu +Zm8KICAgPDwgL1JlZ2lzdHJ5IChBZG9iZSkKICAgICAgL09yZGVyaW5nIChJZGVudGl0eSkKICAg +ICAgL1N1cHBsZW1lbnQgMAogICA+PgogICAvRm9udERlc2NyaXB0b3IgMTkgMCBSCiAgIC9XIFsw +IFsgNTAwIDU4MCA1NzYgNzUwIDM5NiA0OTYgNDQ1IDUwMCA0NDUgNTQyIDQ0MSA1MTYgMzgwIDUx +OCA0NDggMzkwIDM0MiAzODUgMzA1IDM5OSAzODUgNjcyIDQ4NCA2NzIgNDg0IDY3MSA0ODQgNjcx +IDQzMyA2NzEgNDMzIDY3MSA0MzMgNjcxIDQzMyA3NDAgNzAwIDc0MCA1NDAgNTg5IDQ0OCA1ODkg +NDQ4IDU4OSA0NDggNTg5IDQ0OCA1ODkgNDQ4IDcwNSA0OTIgNzA1IDQ5MiA3MDUgNDkyIDcwNSA0 +OTIgNzM2IDYwNSA3MzYgNjA1IDM4MCAzMTggMzgwIDMxOCAzODAgMzE4IDM3OSAzMTQgMzgwIDMx +OCA3MTEgNjMyIDM2OCAzMTggNjY5IDU1NSA1NDkgNTYyIDMyMCA1NjIgMzIwIDU2MiA0NjAgNTYy +IDQzNiA1NjIgMzU2IDcwMyA1OTEgNzAzIDU5MSA3MDMgNTkxIDYxOCA3MDMgNTg5IDc0MyA1MTgg +NzQzIDUxOCA3NDMgNTE4IDYzMCA0MTkgNjMwIDQxOSA2MzAgNDE5IDUxMCA0MzAgNTEwIDQzMCA1 +MTAgNDMwIDU1MiAzODQgNTUyIDM4NCA1NTIgMzg0IDY4OCA1NzAgNjg4IDU3MCA2ODggNTcwIDY4 +OCA1NzAgNjg4IDU3MCA2ODggNTcxIDk1MiA3NTAgNTkzIDQ2MSA1NzAgNDM1IDU3MCA0MzUgMzQz +IDMxOCA0MDAgNDAwIDQwMCA0MDAgNDAwIDQwMCA0MDAgNDAwIDQwMCA0MDAgNzE2IDU3OSA1NzYg +NTUwIDUzOCAzMDAgMzAwIDUwMCAxODAgNDMwIDIzMCAxNzAyIDIyMCA1MDAgMCA2MDAgNjAwIDc2 +MCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDY4MCA4MDAgMzYwIDQ2MCAyODYgNTgw +IDU4MCA3MTggNDgwIDQ2MCA0NjAgNDM2IDQzNiA0NjAgNDYwIDQ2MCA0NjAgNDYwIDQ2MCAzMzAg +MzMwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMzkwIDM5MCAzOTAgMzkwIDM5MCAzOTAgMzEwIDMxMCAz +MTAgMzEwIDMxMCAzMTAgNDA0IDQwNCA0MDQgNDA0IDQwNCA0MDQgNDA0IDI4MCAyODAgXV0KPj4K +ZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL0ZvbnQKICAgL1N1YnR5cGUgL1R5cGUwCiAgIC9CYXNl +Rm9udCAvUEdEUklZK1NXSUZUREFZM0JvbGQKICAgL0VuY29kaW5nIC9JZGVudGl0eS1ICiAgIC9E +ZXNjZW5kYW50Rm9udHMgWyAyMCAwIFJdCiAgIC9Ub1VuaWNvZGUgMTcgMCBSCj4+CmVuZG9iagoy +MSAwIG9iago8PCAvTGVuZ3RoIDIyIDAgUgogICAvRmlsdGVyIC9GbGF0ZURlY29kZQogICAvU3Vi +dHlwZSAvVHlwZTFDCj4+CnN0cmVhbQp4nH1WCVhU1R4/d4bjud6xMYWrqeCgLW5UEpoKZbIKiKzK +GigOiyP7AOOwyKKC2onYF0GQfZMQEc20cd/KNCJ7fWal9arXy77K972+c+nM93pnBkNt8c439zv3 +v/7+5/yXwwELC8BxnFVQiJfHOjfnMAeXlMQYr4zoRI0acBYAAI79naTJQJrFSdYyyUYuWVkYeWsa +bT3B7deV0Iax351senc8zt6ccoppPYe9LEamFk6SATnHzXZ4yTUlNUurid+cYTtfvcD2hcX2S+1s +E2ITdZpkOzu7cd+2Jue2Y97Hiczc3Gh1ckis7aZ4TUqmNj0jy3drWMJz6zYn6mI8kyri9KlpztkA +uAA34AeWAw8G2RV4Am/gD4JBEFgH1oNw8DwIBY7AB0wGS4EXWAtCgDtYAHwBD1aDMBAAAsFcEAGe +lDHluWAxWMHM+TDFUFACGsAB8DY4C66Aj8E34EcgcTJuCjeHW8St4Fw4H66Ma+beki2RrZT5yi7L +eflGeZo8GxskewNnMJDTBrlhmvSUVG18aoLBqBYle3LaaI+U3dJ0yUv0FFwiRC9BuYz8xr7WCMpT +pJctwgSltFD6RfpedBWUgeQrRvIVlLRD2UPeG/UQqW9GSfqFYuy/wHgd9hW8t6sb8yTqLnEhdneD +m2NUftjZbR0VeDLrP6K3oGyUbJmBAJOrQGYlgKSNLhFtBQPNF9cJyiLyLeOGCzERYoSgPEta2ddG +QbmYdLPFq0x+OrnAVpFs5UT2SQNilDBM54obBGULqWaMTYKSLCO2o1NFJ7baQGoYLVpQ/kO6xeC7 +CcU0XHQXGPCPGPBggZSTO2IIs5VOniEzGArlLfK19KO4SiBzpzkLynPkOpMLYgLh5BJbhQrKLLNJ +6spiPl9c6p9Ha+Fuz4H8g5jIMfEg9ZhMx43F7flVvK50YRSs0VdE4xT8pCNdqMFZeEd1yQCvPCQZ +mDEfgVoSg7iW4UwfXSN9IzoI9IB0Ulwi9JJWcSkjnzBvP11r9oX9tXRRDHUrLyCgpf4WvEhcDd8d +xF24Vr9TzWdQq7/i1el3qPl4GphHZaX5xLV1T1tAGb54mKTC+tvhPZF4OY4L8qMqvv7mPcKLOMbP +l87jlfQCCZfeE/NZ7E9KS0ZdRT9hEz0t+gvKRNJoQrUqpST9DO7ccpK+cpQGEpeuPW3rcWrferIG +ukeIaynISU/CmTi7TFfO5+3MWA5rt9fvbsb9uLe9ubutr7JpmEzkySqiEzfjNK0uOSMxX+s/j++b +cO6H+pZu3IJri5uL+LqK1i9gflXuGzrMKw+Sjgf3I4xeDaa55pgHSBiseq0SV5hS76cHUm/VWOpZ +m1OvyZx6VE3l1IXaPX1aN6i6hEc+OEsE3t1ozTbIn22QF9ugK5J8iLjALTWBpcmYZ5najrsK6gv4 +HbEwhDqvckzAfEZ+1SkytY9Y/qxSEhsSSRLFRQLxleaIdoLyeTKZOVILytx6yQuTyNqBNybQbIzM +3chS2m0lFYr7JgmvT1KCIlORWwIrIIJpYDp4AswAM8EsYA1swDzWEfxY3zD1A1PnSAGvgSpQDWpA +LagDe8H74Cq4Bj4Aw+Cf4H/gN86R28ClcxlcJtfJnee+kqlkobKtsnfkU+U28kQ5ll+X/yy/azHR +wsUiyqLL4pTFR3AS3ARfg9Xw1oSQCQY0ASHEo4lIQAo0CT2GlGgyehxNQVORJbJCIpqGpqMn0Aw0 +E81C1sgGzUYqZIvmIFfkhtyRB1qNPJEX8kZrkA9ai3yRH/JHASgQBaF1aD0KRiEoFIWhcBSBXkWR +KAptQBtRNNqE1CgGxaI4FI82xyQlxcT0JA4O9vYODib2xKgU9x8yjMsH6DCGCnrNOOqdjbeSQIz3 +uzeSbCn+a2Oct55RihglqIFaSb/Ce2o32vF+WoHx1it6B+NJFy0TYl/7PZqg4vrvrGET6+XfWWsY +i/Tj8qO0H9+zgnXv618wnnPKwjoSjXHzK42fSbuI3njoJr4j/fT+PtxMAzHEuk+y3Y0+NFLSjuk5 +GM+YrdaaHX4tXYKKiqePlewlc5JxWDGlOLwsCSfSOW/vGbjLNPwwDTF6+Ese55qYwRyMdRdyvjGO +vsMsk2gp/HXVNWOEAbNWSEYamYA/E7isp2uNblBxxaTxIiMc30odaN1LZO+QiZLCKGdyyGNGcImF +MkQqKcRqWuJqAlXKQJlgUvXT5nI4YS6Hq+ZySKQrS/KI971+0U6eOXK/HBQPFYPX/WJoMxWDorW2 +MIROjaGWjqoErKnNreHL++Ep4nL1iyNMl1rTBdSO/eD5hE9V1/CHp89f4nUtMF4TqYnGfOSWti8J +aPr3HdWbuFPbso2vK+u/AbMbdNUmx+OTJoPOg9vfKCzJwzxdSR+nnvSZe9V8/cMx+Kvuw38HMsSd +efU5fHGyCfHLy8cRdxJLAlQKOpHOpPOoPYXvJnzMQN0YB7VeE4L5+KSOm2R2+5cj++oLtCocWhBM +J+XzSYjMrP/hLP6UP775UOhsxWas3RaXFpXg7J9FZfwKYwnMcyzQJ+FUrKnX1vB5xanLYUNxx64W +1gLb9w50HDvw8cVGIuM/l0pg3Wc1TT24E7+Z217AQu78AuaUpZVmspArDtEN2Ddzdw7LejW1+FPf +2kQLYe6SjO1BOAqv3hfTw2/bnr4Sdmwdyj+Mz+PmskNNx9sId6qV2PBDpOhvT/GVh06RyFX399rb +OP/hyXLSPFkaHjFZQsyDRG0eJAq65l67jqWah4VZ8o178TLOjxvz0lx7G7LNTE3PSMpMLsp1ms8n +JfxCk4gDGzDhOK5vIfGCFz+tqe5kI6KxiI2IytKO23B7pa5c/2CKvGyM+6O3vx+kYyHtfURIYQ+G +5ECdFlMNhSMJH35FXvqWaAh0PeChUgx1bVxKxbhnV0enHvmSiAe/H1Y95NQc4S/N9bdhGwEjZNYZ +vB/X7Wko5KvLev8Fd1Rsq8zE3jjCJ4jO5BWL6cQAexWO7Is/G3cutjELJ+Kk3J1x7Jw9hzIb+Kzi +nOWwqcCQcwLfwv+9gD/HF7YcDBjc2K3Zj7txV2tVOz6Gj6e35PCNZS2fQ31VWpnp1BdluhjtYfaC +Lv0ZfBJf6+vv4wuboD4voSALb8E791ef40ek+dCUd1ocO5Z33mMROMfTGJj7oiHpbXwbH750mcxj +mxX0UJuYP0jcimooyMxdBv2pa+hz8ezuk9dUcZh/kwQyS3++NZ3Hl68cucPvcnzgFuX8t7co57Fb +VKHpFlVHgmFZS/lR3MHSYEzSblzy2WV0STLOG5P8YwRnzRH0myOIpDWsfrLN9eP8QP0cN9dPX8nB +luPd351oJdasfIoHifsjolPTGS27YNvhzsqj2/mbuXQF1S61b0yHR3s6KnuLeOKYcAy/RWZklsJ0 +ddbO6CqeTukgTkT7yY2sNrgxJac4vYynC7qg4hEPjtYkRKXxtTr40eGrJ/FNfiilL06tzdDMxvHN +ukOF/KOU7z//B39W2BAKZW5kc3RyZWFtCmVuZG9iagoyMiAwIG9iagogICAyNjEzCmVuZG9iagoy +MyAwIG9iago8PCAvTGVuZ3RoIDI0IDAgUgogICAvRmlsdGVyIC9GbGF0ZURlY29kZQo+PgpzdHJl +YW0KeJxdks9ugzAMxu88RY7doYLSgFcJVZq6Sw/7o3V7AEhMh7QGlNJD3352vqqTdoD8cL7PNonz +3f55H4bZ5O9xdAeeTT8EH/k8XqJj0/FxCNmqNH5w8+0rvd2pnbJczIfreebTPvRj1jQm/5DN8xyv +ZvHkx44fMmNM/hY9xyEczeJrd0DocJmmHz5xmE2RbbfGcy/pXtrptT2xyZN5ufeyP8zXpdj+FJ/X +iU2ZvldoyY2ez1PrOLbhyFlTFFvT9P024+D/7a0tLF3vvtuYNfVKpEUhi/AavFZmMAtXlFgWiVeI +V8JlkVgWiZeIl8rQ10m/AW+Ue7A01hDykOYheEm9hB5IeyALtsrIQ5rHojervRFqkdaqoKlSrQ61 +Ou0T+jL9C3JWmrN+hOZR2YGd5qyRs9Y49LXqLfQ26T3iXnij/ZfFKtWFt1YvQU+qJ5wV6VkRzpz0 +zC3YKlOLeJsu7nZDeoU6a/fZcJcYZSzSQKZ50EkYAt9ndhondaXnF1p7vskKZW5kc3RyZWFtCmVu +ZG9iagoyNCAwIG9iagogICAzODMKZW5kb2JqCjI1IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3Jp +cHRvcgogICAvRm9udE5hbWUgL0hRUUtGUCtTV0lGVERBWTNCb2xkSXRhbGljCiAgIC9Gb250RmFt +aWx5IChTV0lGVERBWTMpCiAgIC9GbGFncyA0CiAgIC9Gb250QkJveCBbIC0zNzIgLTExODMgMTYw +NCA5MzggXQogICAvSXRhbGljQW5nbGUgMAogICAvQXNjZW50IDc3MAogICAvRGVzY2VudCAtNDMw +CiAgIC9DYXBIZWlnaHQgOTM4CiAgIC9TdGVtViA4MAogICAvU3RlbUggODAKICAgL0ZvbnRGaWxl +MyAyMSAwIFIKPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0ZvbnQKICAgL1N1YnR5cGUgL1R5 +cGUxCiAgIC9CYXNlRm9udCAvSFFRS0ZQK1NXSUZUREFZM0JvbGRJdGFsaWMKICAgL0ZpcnN0Q2hh +ciAzMgogICAvTGFzdENoYXIgMTQ2CiAgIC9Gb250RGVzY3JpcHRvciAyNSAwIFIKICAgL0VuY29k +aW5nIC9XaW5BbnNpRW5jb2RpbmcKICAgL1dpZHRocyBbIDIyMCAwIDAgMCAwIDAgMCAwIDAgMCAw +IDAgMCAwIDI3MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA2MzAgMCAwIDAg +MCAwIDAgNzE2IDAgMCAwIDAgMCA2NTYgMCAwIDAgMCAwIDU3NyAwIDAgODk5IDAgNTY4IDAgMCAw +IDAgMCAwIDAgNTIyIDUyMyA0MDkgNTMxIDQzNiAzNTAgNTExIDU0OSAzMDQgMCA1MjMgMjk1IDc4 +OCA1NDUgNDg3IDUyOSA1MTIgNDAyIDM2MiAzMjYgNTQ4IDQ3NSA2OTYgNDYyIDUxNSA0MDEgMCAw +IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDE4OCBdCiAgICAvVG9V +bmljb2RlIDIzIDAgUgo+PgplbmRvYmoKMjYgMCBvYmoKPDwgL0xlbmd0aCAyNyAwIFIKICAgL0Zp +bHRlciAvRmxhdGVEZWNvZGUKICAgL1N1YnR5cGUgL0NJREZvbnRUeXBlMEMKPj4Kc3RyZWFtCnic +Y2RgYWFgZGQUCQ73dAtxcYw0dsrPSfEsSczJTGZgZGFgYGAEYqcf0j9kunnkfvAz/JBl/CHH9EOe ++YcIyx8Omd+JMmwuv+xY+3iUZIFqu3hUgBTDAR5VELWbH0SeEGzkYWJgZWRk49N28HRMyU9K9UxJ +zSvJLKl0zi+oLMpMzyhR0EjWVDAyMDTVUchOzSnLzNPR0YG7SAHkJAWIm+CCDAxMQKcxMoPdx8DM +wMzIqJS3p3vvD8O9jHv3fj+wl3mv2A+VH1P/qLDt/ZMs+sPw+4E/hux8u783f38u6l3aXf19Xvek +jaxm3yeJHp3j8Vvod0zAb2vDwIbz34W+xxz4bvVUftEO0d8Wv/l/x/4u+6263va7+HeL7/zfY7+X +fVdNv/lbXJ5v2fc7P5xFq/JY97eviOk25fitHGFo65Gy/aFc95tZt27s46hbwPpbPCpAqVuR4zfr +lahP3wW/G7z5HvKdwX6nhtys7/2iv03+yW1s/W7yS46VDxHaPKBQUwQF5wKhmlk/PLu/x07f0Mf2 +u6qbHSwj/KND5Eej6Bwerh4ePoZWRkYmZhZWNnYOTi5uHl4+fgFBIWERUTFxCUkpaRlZOXkFRSVl +FVU1dQ1NLW0dXT19A0MjYxNTM3MLSytrG1s7ewdHJ2cXVzd3D08vbx9fP/+AwKDgkNCw8IjIqOiY +2Lj4hMSk5JTUtPSMzKzsnNy8/ILCouKS0rLyisqq6prauvqGxqbmltY27sEAAJhry3MKZW5kc3Ry +ZWFtCmVuZG9iagoyNyAwIG9iagogICA1NjUKZW5kb2JqCjI4IDAgb2JqCjw8IC9MZW5ndGggMjkg +MCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp4nF2QwWrDMAyG734KHbtDcZJS +2CEYRnfJYetotgdwbDkzLLZRnEPefo5SOpjAht/6P/Fb8tK9dsFnkB8UTY8ZnA+WcI4LGYQBRx9E +3YD1Jt8V32bSScgC9+ucceqCi6JtQd5Kc860wuHFxgGfBADIK1kkH0Y4fF36/alfUvrBCUOGSigF +Fl0Z96bTu54QJMPHzpa+z+uxYH+OzzUhNKzrPZKJFuekDZIOI4q2KqWgdaWUwGD/9ZudGpz51sTu +urir0/CsWDWs7JnZu2ubsn35EdEsRCUd74VjbYF8wMfqUkwbxecX6UZzeQplbmRzdHJlYW0KZW5k +b2JqCjI5IDAgb2JqCiAgIDIzMwplbmRvYmoKMzAgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlw +dG9yCiAgIC9Gb250TmFtZSAvUFdDREVaK1NXSUZUREFZM0JvbGRJdGFsaWMKICAgL0ZvbnRGYW1p +bHkgKFNXSUZUREFZMykKICAgL0ZsYWdzIDQKICAgL0ZvbnRCQm94IFsgLTM3MiAtMTE4MyAxNjA0 +IDkzOCBdCiAgIC9JdGFsaWNBbmdsZSAwCiAgIC9Bc2NlbnQgNzcwCiAgIC9EZXNjZW50IC00MzAK +ICAgL0NhcEhlaWdodCA5MzgKICAgL1N0ZW1WIDgwCiAgIC9TdGVtSCA4MAogICAvRm9udEZpbGUz +IDI2IDAgUgo+PgplbmRvYmoKMzEgMCBvYmoKPDwgL1R5cGUgL0ZvbnQKICAgL1N1YnR5cGUgL0NJ +REZvbnRUeXBlMAogICAvQmFzZUZvbnQgL1BXQ0RFWitTV0lGVERBWTNCb2xkSXRhbGljCiAgIC9D +SURTeXN0ZW1JbmZvCiAgIDw8IC9SZWdpc3RyeSAoQWRvYmUpCiAgICAgIC9PcmRlcmluZyAoSWRl +bnRpdHkpCiAgICAgIC9TdXBwbGVtZW50IDAKICAgPj4KICAgL0ZvbnREZXNjcmlwdG9yIDMwIDAg +UgogICAvVyBbMCBbIDUwMCA1NDEgNTIwIF1dCj4+CmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9G +b250CiAgIC9TdWJ0eXBlIC9UeXBlMAogICAvQmFzZUZvbnQgL1BXQ0RFWitTV0lGVERBWTNCb2xk +SXRhbGljCiAgIC9FbmNvZGluZyAvSWRlbnRpdHktSAogICAvRGVzY2VuZGFudEZvbnRzIFsgMzEg +MCBSXQogICAvVG9Vbmljb2RlIDI4IDAgUgo+PgplbmRvYmoKMSAwIG9iago8PCAvVHlwZSAvUGFn +ZXMKICAgL0tpZHMgWyA5IDAgUiBdCiAgIC9Db3VudCAxCj4+CmVuZG9iagozMiAwIG9iago8PCAv +Q3JlYXRvciAoY2Fpcm8gMS4xMy4xIChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQogICAvUHJv +ZHVjZXIgKGNhaXJvIDEuMTMuMSAoaHR0cDovL2NhaXJvZ3JhcGhpY3Mub3JnKSkKPj4KZW5kb2Jq +CjMzIDAgb2JqCjw8IC9UeXBlIC9DYXRhbG9nCiAgIC9QYWdlcyAxIDAgUgo+PgplbmRvYmoKeHJl +ZgowIDM0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAzNDYzNSAwMDAwMCBuIAowMDAwMDAzMjA5 +IDAwMDAwIG4gCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMzE4NiAwMDAwMCBuIAowMDAwMDE2 +MDg0IDAwMDAwIG4gCjAwMDAwMjg3MzUgMDAwMDAgbiAKMDAwMDAzMjM5NSAwMDAwMCBuIAowMDAw +MDM0NDY2IDAwMDAwIG4gCjAwMDAwMDMzNzUgMDAwMDAgbiAKMDAwMDAwMzU4OSAwMDAwMCBuIAow +MDAwMDE0NTE3IDAwMDAwIG4gCjAwMDAwMTQ1NDIgMDAwMDAgbiAKMDAwMDAxNTc5MCAwMDAwMCBu +IAowMDAwMDE1ODE0IDAwMDAwIG4gCjAwMDAwMTcxNzIgMDAwMDAgbiAKMDAwMDAyNjA3MCAwMDAw +MCBuIAowMDAwMDI2MDk0IDAwMDAwIG4gCjAwMDAwMjczMDggMDAwMDAgbiAKMDAwMDAyNzMzMiAw +MDAwMCBuIAowMDAwMDI3NjAyIDAwMDAwIG4gCjAwMDAwMjg4OTggMDAwMDAgbiAKMDAwMDAzMTYx +MCAwMDAwMCBuIAowMDAwMDMxNjM0IDAwMDAwIG4gCjAwMDAwMzIwOTYgMDAwMDAgbiAKMDAwMDAz +MjExOSAwMDAwMCBuIAowMDAwMDMyOTEzIDAwMDAwIG4gCjAwMDAwMzM1ODQgMDAwMDAgbiAKMDAw +MDAzMzYwNyAwMDAwMCBuIAowMDAwMDMzOTE5IDAwMDAwIG4gCjAwMDAwMzM5NDIgMDAwMDAgbiAK +MDAwMDAzNDIxOCAwMDAwMCBuIAowMDAwMDM0NzAwIDAwMDAwIG4gCjAwMDAwMzQ4MjggMDAwMDAg +biAKdHJhaWxlcgo8PCAvU2l6ZSAzNAogICAvUm9vdCAzMyAwIFIKICAgL0luZm8gMzIgMCBSCj4+ +CnN0YXJ0eHJlZgozNDg4MQolJUVPRgo= +--=_be6bc52b94449e229e651d02e56a25f1-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-382.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-382.eml new file mode 100644 index 000000000..f34b89fc3 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-382.eml @@ -0,0 +1,9 @@ +From: MAILER-DAEMON@mta-09.someserver.com (Mail Delivery System) +To: to@here.com +Subject: Test +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-401.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-401.eml new file mode 100644 index 000000000..386fdad8a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-401.eml @@ -0,0 +1,9 @@ +From: from@there.com +To: to@here.com +Subject: 1;00pm Client running few minutes late +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410.eml new file mode 100644 index 000000000..e5fe0c628 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410.eml @@ -0,0 +1,16 @@ +From: from@there.com +To: to@here.com +Subject: =?ISO-2022-JP?B?GyRCIXlCaBsoQjEzMhskQjlmISEhViUsITwlRyVzGyhCJhskQiUoJS8lOSVGJWolIiFXQGxMZ0U5JE4kPyRhJE4jURsoQiYbJEIjQSU1JW0lcyEhIVo3bjQpJSglLyU5JUYlaiUiISYlbyE8JS8hWxsoQg==?= +Date: Wed, 13 Sep 2017 13:05:45 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------B832AF745285AEEC6D5AEE42" + +Hi +--------------B832AF745285AEEC6D5AEE42 +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="=?ISO-2022-JP?B?GyRCIXlCaBsoQjEzMhskQjlmISEhViUsITwlRyVzGyhCJhskQiUoJS8lOSVGJWolIiFXQGxMZ0U5JE4kPyRhJE4jURsoQiYbJEIjQSU1JW0lcyEhIVo3bjQpJSglLyU5JUYlaiUiISYlbyE8JS8hWxsoQg==?=" + +SGkh +--------------B832AF745285AEEC6D5AEE42-- \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410b.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410b.eml new file mode 100644 index 000000000..b260a1e06 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-410b.eml @@ -0,0 +1,22 @@ +From: from@there.com +To: to@here.com +Subject: =?iso-8859-1?Q?386_-_400021804_-_19.,_Heiligenst=E4dter_Stra=DFe_80_-_081?= + =?iso-8859-1?Q?9306_-_Anfrage_Vergabevorschlag?= +Date: Wed, 13 Sep 2017 13:05:45 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------B832AF745285AEEC6D5AEE42" + +Hi +--------------B832AF745285AEEC6D5AEE42 +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; + name="=?iso-8859-1?Q?2021=5FM=E4ngelliste=5F0819306.xlsx?=" +Content-Description: =?iso-8859-1?Q?2021=5FM=E4ngelliste=5F0819306.xlsx?= +Content-Disposition: attachment; + filename="=?iso-8859-1?Q?2021=5FM=E4ngelliste=5F0819306.xlsx?="; size=11641; + creation-date="Mon, 10 Jan 2022 09:01:00 GMT"; + modification-date="Mon, 10 Jan 2022 09:01:00 GMT" +Content-Transfer-Encoding: base64 + +SGkh +--------------B832AF745285AEEC6D5AEE42-- \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-412.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-412.eml new file mode 100644 index 000000000..f28b81a71 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-412.eml @@ -0,0 +1,216 @@ +Return-Path: +Delivered-To: gmx@tonymarston.co.uk +Received: from ion.dnsprotect.com + by ion.dnsprotect.com with LMTP + id YFDRGeZ6d2SlCRUAzEkvSQ + (envelope-from ) + for ; Wed, 31 May 2023 12:50:46 -0400 +Return-path: +Envelope-to: gmx@tonymarston.co.uk +Delivery-date: Wed, 31 May 2023 12:50:46 -0400 +Received: from mail-vi1eur04olkn2050.outbound.protection.outlook.com ([40.92.75.50]:23637 helo=EUR04-VI1-obe.outbound.protection.outlook.com) + by ion.dnsprotect.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + (Exim 4.96) + (envelope-from ) + id 1q4P28-005pTm-0E + for gmx@tonymarston.co.uk; + Wed, 31 May 2023 12:50:46 -0400 +ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; + b=SYBG6BEOiWsmVfcgXUQJ0moS1SuG/IdTK6DIT4H3g7CQ+hbWIbItTxOhFzJiHP+q0uz+XzR1FzX2Daso+4iKotX7x2ViHIA0Hs65xUZVFtvflMsUrB+5RLlf3Pr7DiNKguQQtC+R2IBLvedc+IqElnMrTHcxLVS2gWl89MZx5Q0bXGWW/9wBVq6yvc6C69ynppcEdD0QZsoUQlp2DgzDpg8iG3y6dYGxFiTvLzw08nTQiCuqi8qQ+nmHyeeItIiAmyKynvyiL+kh4frcSDS67r6PU/CBxvto/nP3RCAxHuzJEGOpS7LJPqoJAlRSrUp2zpeEMpmDFJUE/Jo0K+EgcQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; + s=arcselector9901; + h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; + bh=ISg5C/1AgVASEPkGp/cgowfc/y9qywGvXMTv5yjJffs=; + b=eVYGErUWMxOeFGLg2nPuB0E/ngKet0hEVcN8Ay4ujGFY4k7i+1hrmnOMD6XiaIk3gVrqPalsmDjmEHpS0zV3+fPPTSktlSvkLrUr5ViVI1kMVBbBQsowLD5x3FpX7fnP2q17WPQ2P6R8Ibudkdnei8uq7gZhc3CSDLv4PfNma45H0FmdaB40mF2dCYzj5hEzr6jmMliANHJjznuDEFEUH3CfS1/iIA9rzhBKPKtahipTNeYiLqvZpKo1fO/XkZ57T44fqHkocfCyEK3Y1rehWudmkU8a9eEZlU5nBC6xoGO3P5Q1XIUNEHFmx2HH7eO8IgGzq/vbLMhcvbc3Ysdb2A== +ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; + dkim=none; arc=none +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; + s=selector1; + h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; + bh=ISg5C/1AgVASEPkGp/cgowfc/y9qywGvXMTv5yjJffs=; + b=Qv71Bx+LsM9Lo0uen0vxQzWI3ju4Q095ZMkKPXDaKsd5Y8dA3QteMpAPhy3/mAdP1+EV8NviDBhamtTG4qMO+zEqu/pyRpBGZOtjyiJGKh7aFh2bbodOkJkiGqH3jPwYBnE7T1XAqDVFmvRpuqIkqBe9FXeCZKRrF/Na5Y+zuklH7ebuGQVzIK+xol6q7BDgb/oLul7Wa3r3Lw40cPW5leUgwxngRFMucUVVO5aJ4MWlk76CmcN8XqgwVcFaACY80HLWRqRZfM8n24/KzV9nKSZIQFCgJi2CiqnEWVRSZZtZ9SudJJv4S3C/gU4OYoiFKr7GkEQibyqE2QkGHCBA1g== +Received: from PAXP193MB2364.EURP193.PROD.OUTLOOK.COM (2603:10a6:102:22b::9) + by DB8P193MB0773.EURP193.PROD.OUTLOOK.COM (2603:10a6:10:15a::10) with + Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6455.22; Wed, 31 May + 2023 16:50:03 +0000 +Received: from PAXP193MB2364.EURP193.PROD.OUTLOOK.COM + ([fe80::b962:59b:2d33:85c2]) by PAXP193MB2364.EURP193.PROD.OUTLOOK.COM + ([fe80::b962:59b:2d33:85c2%5]) with mapi id 15.20.6455.020; Wed, 31 May 2023 + 16:50:03 +0000 +From: Tony Marston +To: "gmx@tonymarston.co.uk" +Subject: RE: TEST MESSAGE +Thread-Topic: TEST MESSAGE +Thread-Index: AQHZjysmbQn8p2cYOEawNV6ywnFmN690oIyAgAAA5rw= +Date: Wed, 31 May 2023 16:50:03 +0000 +Message-ID: + +References: + + <944a7d16fcb607628f358cdd0f5ba8c0@tonymarston.co.uk> +In-Reply-To: <944a7d16fcb607628f358cdd0f5ba8c0@tonymarston.co.uk> +Accept-Language: en-GB, en-US +Content-Language: en-GB +X-MS-Has-Attach: +X-MS-TNEF-Correlator: +x-ms-exchange-messagesentrepresentingtype: 1 +x-tmn: [ABOzTq1ytyWYuvBD5A4I78Eqna1hBLeM] +x-ms-publictraffictype: Email +x-ms-traffictypediagnostic: PAXP193MB2364:EE_|DB8P193MB0773:EE_ +x-ms-office365-filtering-correlation-id: 7fbd6771-9a0d-495d-c4d3-08db61f714a6 +x-microsoft-antispam: BCL:0; +x-microsoft-antispam-message-info: + fwWKs8Qs/JyQ+pSnCNC804PQ86JYn/R63U7P6WCeXLC/fVSGqcAnslOc2vbxC2cUeTPPfow1WAz3f73/7Uk+byKxiE6L48WkgL6BFKVkYCwPKcQ3ps6KyEdGL6uUvPqYKwf5gFgUiTt+fKDiR/GJljj6qmN51jd5lUBvLf1g59q3LryUC+lEy6iLQ8cjCivzmBcR+0C2+uaa/xsjJxokbIEQoMicjjUiVWFkxRFBDr6FO8kEQyzzs70pNivK6mcXpVeJSOiLQfYa/2Q5QDYhE8kznG1EYUzHBQD/sLp/maUgmpKj1b8ObeI13QXed1qih+CtdLYAmPs5GPaoz8aY7pmaxroKLjBAqfOAC2IeQ3grxdQ8eRXlrnZ29cQnvD9tDryUvE9nyQLinaM2Dft4MueHvBTL5+WOTNnVQB98zVjnop8iVkwNrBKzPYiox9ufs9XFXNl0+2fFn66647ET7y/DkBKcszTKYF5RRp5o59QAh8rUTsaKeGJkPkyowZd+i6R12NIavL+eOOgnKvziTTbNl1lGgP+3zTKbgbb6K+DxfbKNl1zaTNvonOHwzI3jfdkDRtg5BvZVKstyl9AfZqo6OZ7ii3JKgVquRVWAtEQ6J6tx1Va/nTVrn1478+Dj +x-ms-exchange-antispam-messagedata-chunkcount: 1 +x-ms-exchange-antispam-messagedata-0: + =?us-ascii?Q?EMaSeqWhMBslXR7KptI34/opub+lBzTReVt3ACHDu/w7NvVUPpdp4YhwogpL?= + =?us-ascii?Q?8V9o/Zj+8vv6zZ7YL0n2NpODi8fzrPScgRiZGtJmfS58OqfgW2yygp1BmawZ?= + =?us-ascii?Q?y99Omv39THENDmCAba4d8zYLikOc+HJUfhpWeb/L9yqut7T2QkPFJYoeN5vU?= + =?us-ascii?Q?LeJ1hoPlguhNnDwMtE3HTgAl0Hbesms0Rb7wGaTDsgAc7XOO+8XpqLamnU0m?= + =?us-ascii?Q?zPpkQXV8+V5dFU2HxgIcYPYSaTX1CLPCdNcCAr1uHPnN81Ntm9Jb7fpYs1oA?= + =?us-ascii?Q?tgzPMwt37Ks9eQucJWZ5LQnNmZl/kYtVnvkylqYYMWiAg3y2XtjVkW/Ut/V2?= + =?us-ascii?Q?6vMfyCB5fEGJrn/uCp+KwL1s7s/4B332Bn4zvwpYd5TioMSGf9Rdp157eAfg?= + =?us-ascii?Q?LiNlLjDFdRc5SSEkUEl1TeX0FOQLsaCsQQqC/hzb10boa49GuxpoKwRmwhAO?= + =?us-ascii?Q?LZ2+veS5Jr1qWngBGo4MTkEq7nD6vBRIXQmKiLMpJc+Gk3/PCADL+H0IRH0+?= + =?us-ascii?Q?4uHnvcVr6CrDDZ2BEwcaWOa/ct8yUI5G9SC5gFP53TaS2llCnYwHAX1PkMAo?= + =?us-ascii?Q?w2LHFHE5I5dtQQJHaWNGMJGYdPmb9dDrksggLWXN+IxsxvFcFNSK2GPaqOMJ?= + =?us-ascii?Q?H4ht1rpqHTlU0uzgjb19gKCCcBdZfIzv118RTjFYG+EX/rsHlNRei/OWdTBF?= + =?us-ascii?Q?xf5cdnap836rQmre5ZoubNsSw2qKSRJhmZH1pCHoCFLtreM1fk7kkVJfkUz5?= + =?us-ascii?Q?ApMa03dEfFvzVv5wvPdWBLiCqzI6z6z8fUmwg2XfvK9Nyxb1AOZoT7JUXnp2?= + =?us-ascii?Q?Me6dTKqGKsBx87Dtny+fANHqgOm+Eo/pBZqyXwN93udbltxPmtNJ84MJJjyx?= + =?us-ascii?Q?vbEiDnMVb4knBO+sBqlKAVUv1F9ZJA2oUTrOD7t1xx6nBmQTgoYN6zsi+dgw?= + =?us-ascii?Q?nPebsl1/6fUy73FWLUKkeA64PeSa00Zi/q53ylXmUZV4Pc+11blKdL8o+p32?= + =?us-ascii?Q?dTD0ndul0WvvpQf8RdYNtGJ/BMurqNfvHq9wJo7Iu4fgTElR50ngwEsr28Bc?= + =?us-ascii?Q?G81pAb2fNhID6ewyOGfj87kqybxUhv1E+4pquh770UagjD1J3rKAUiw1sxWp?= + =?us-ascii?Q?u+FSmd7HKgd2cKJsmMErnQelF3DNozw5d0qdNELXZNO03xlMiADVvhqEJuqc?= + =?us-ascii?Q?uArdsSo2hyApUaiB+dM4Fp+oeiGienEQl64NJ7QFxRb/h96J0iTL3Vp8+8Y?= + =?us-ascii?Q?=3D?= +Content-Type: multipart/alternative; + boundary="_000_PAXP193MB2364F1160B9E7C559D7D897ABB489PAXP193MB2364EURP_" +MIME-Version: 1.0 +X-OriginatorOrg: sct-15-20-4755-11-msonline-outlook-80ceb.templateTenant +X-MS-Exchange-CrossTenant-AuthAs: Internal +X-MS-Exchange-CrossTenant-AuthSource: PAXP193MB2364.EURP193.PROD.OUTLOOK.COM +X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 +X-MS-Exchange-CrossTenant-Network-Message-Id: 7fbd6771-9a0d-495d-c4d3-08db61f714a6 +X-MS-Exchange-CrossTenant-originalarrivaltime: 31 May 2023 16:50:03.3982 + (UTC) +X-MS-Exchange-CrossTenant-fromentityheader: Hosted +X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa +X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 +X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8P193MB0773 +X-Spam-Status: No, score=-1.6 +X-Spam-Score: -15 +X-Spam-Bar: - +X-Ham-Report: Spam detection software, running on the system "ion.dnsprotect.com", + has NOT identified this incoming email as spam. The original + message has been attached to this so you can view it or label + similar future email. If you have any questions, see + root\@localhost for details. + Content preview: Here is my reply to your reply. Tony Marston From: gmx@tonymarston.co.uk + Sent: 31 May 2023 17:46 To: Tony Marston + Subject: Re: TEST MESSAGE + Content analysis details: (-1.6 points, 8.0 required) + pts rule name description + ---- ---------------------- -------------------------------------------------- + -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% + [score: 0.0005] + 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail + provider + [tonymarston[at]hotmail.com] + -0.0 SPF_PASS SPF: sender matches SPF record + 0.5 SUBJ_ALL_CAPS Subject is all capitals + -0.0 SPF_HELO_PASS SPF: HELO matches SPF record + 0.0 HTML_MESSAGE BODY: HTML included in message + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily + valid + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.0 T_SCC_BODY_TEXT_LINE No description available. +X-Spam-Flag: NO +X-From-Rewrite: unmodified, no actual sender determined from check mail permissions + +--_000_PAXP193MB2364F1160B9E7C559D7D897ABB489PAXP193MB2364EURP_ +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Here is my reply to your reply. + +Tony Marston + +From: gmx@tonymarston.co.uk +Sent: 31 May 2023 17:46 +To: Tony Marston +Subject: Re: TEST MESSAGE + +On 2023-05-25 13:06, Tony Marston wrote: +Here is my reply to your message +> Tony Marston + + +--_000_PAXP193MB2364F1160B9E7C559D7D897ABB489PAXP193MB2364EURP_ +Content-Type: text/html; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
+

Here is my reply to your reply.

+

 

+

Tony Marston

+

 

+
+

From: gmx@tonymarston.co.uk
+Sent: 31 May 2023 17:46
+To: Tony Marston
+Subject: Re: TEST MESSAGE

+
+

 

+

On 2023-05-25 13:06, Tony Marston wrote:
+Here is my reply to your message
+> Tony Marston

+

 

+
+ + + +--_000_PAXP193MB2364F1160B9E7C559D7D897ABB489PAXP193MB2364EURP_-- \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-413.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-413.eml new file mode 100644 index 000000000..9f0cbfa2c --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-413.eml @@ -0,0 +1,32 @@ +Return-Path: +Delivered-To: gmx@tonymarston.co.uk +Received: from ion.dnsprotect.com + by ion.dnsprotect.com with LMTP + id oPy8IzIke2Rr4gIAzEkvSQ + (envelope-from ) + for ; Sat, 03 Jun 2023 07:29:54 -0400 +Return-path: +Envelope-to: gmx@tonymarston.net +Delivery-date: Sat, 03 Jun 2023 07:29:54 -0400 +Received: from [::1] (port=48740 helo=ion.dnsprotect.com) + by ion.dnsprotect.com with esmtpa (Exim 4.96) + (envelope-from ) + id 1q5PSF-000nPQ-1F + for gmx@tonymarston.net; + Sat, 03 Jun 2023 07:29:54 -0400 +MIME-Version: 1.0 +Date: Sat, 03 Jun 2023 07:29:54 -0400 +From: radicore +To: gmx@tonymarston.net +Subject: Test Message +User-Agent: Roundcube Webmail/1.6.0 +Message-ID: +X-Sender: radicore@radicore.org +Content-Type: text/plain; charset=US-ASCII; + format=flowed +Content-Transfer-Encoding: 7bit +X-From-Rewrite: unmodified, already matched + +This is just a test, so ignore it (if you can!) + +Tony Marston diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-414.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-414.eml new file mode 100644 index 000000000..302e4492e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/issue-414.eml @@ -0,0 +1,27 @@ +From: from@there.com +To: to@here.com +Subject: Test +Date: Fri, 29 Sep 2017 10:55:23 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------5B1F217006A67C28E756A62E" + +This is a multi-part message in MIME format. + +--------------5B1F217006A67C28E756A62E +Content-Type: text/plain; charset=UTF-8; + name="../../example/MyFile.txt" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="../../example/MyFile.txt" + +TXlGaWxlQ29udGVudA== +--------------5B1F217006A67C28E756A62E +Content-Type: text/plain; charset=UTF-8; + name="php://foo" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="php://foo" + +TXlGaWxlQ29udGVudA== +--------------5B1F217006A67C28E756A62E-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/ks_c_5601-1987_headers.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/ks_c_5601-1987_headers.eml new file mode 100644 index 000000000..a8de3d088 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/ks_c_5601-1987_headers.eml @@ -0,0 +1,10 @@ +Subject: =?ks_c_5601-1987?B?UkU6IMi4v/i01LKyIEVyc2m01MDMILjevcPB9rimILq4s8K9wLTP?= + =?ks_c_5601-1987?B?tNku?= +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +Thread-Topic: =?ks_c_5601-1987?B?yLi/+LTUsrIgRXJzabTUwMwguN69w8H2uKYgurizwr3AtM+02S4=?= +From: =?ks_c_5601-1987?B?seggx/bB+A==?= +To: to@here.com + +Content diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mail_that_is_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mail_that_is_attachment.eml new file mode 100644 index 000000000..89215cf8a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mail_that_is_attachment.eml @@ -0,0 +1,28 @@ +Sender: xxx@yyy.cz +MIME-Version: 1.0 +Message-ID: <2244696771454641389@google.com> +Date: Sun, 15 Feb 2015 10:21:51 +0000 +Subject: Report domain: yyy.cz Submitter: google.com Report-ID: 2244696771454641389 +From: noreply-dmarc-support via xxx +To: xxx@yyy.cz +Content-Type: application/zip; + name="google.com!yyy.cz!1423872000!1423958399.zip" +Content-Disposition: attachment; + filename="google.com!yyy.cz!1423872000!1423958399.zip" +Content-Transfer-Encoding: base64 +Reply-To: noreply-dmarc-support@google.com + +UEsDBAoAAAAIABRPT0bdJB+DSwIAALgKAAAuAAAAZ29vZ2xlLmNvbSFzdW5mb3guY3ohMTQyMzg3 +MjAwMCExNDIzOTU4Mzk5LnhtbO1WwY6bMBC971dEuQcDIQSQQ3rqF7RnZIwh7oJt2WY32a+viQ2h +u9moqnarqOop8Gbmjd/4OQbuj127eCJSUc52y8DzlwvCMK8oa3bL79++rpLlYp8/wJqQqkT4MX9Y +LKAkgktddESjCmk0YAblsikY6kjecN60xMO8g2ACbQ7pEG1zxg1De1pVHZJ4pXox0H2Zl9k8V3PU +EhWYM42wLiireX7QWmQAuErvUgkQKCkDiKlnIj1x2tunXRjF8SbxDfFbMtvFaaJVHoZRFKfxdhtE +myiOgnWSQnAJ23SjmxQSscYpM1BJGsryIArXyTb0fdPMImOcsOocTTfJOjWUw7slA7+yTd3mA4aC +txSfCtGXLVUHMi2Em1GxXPVGytHDL4bMIjaMqkfa5RIC++BAJeozNvxaSOSS/CBYQyAcoi6QGjGB +dR4MyoaH80qvrcrMEnM5LlDy52kEivcSk4KKPIz9bVYnpZ9Fvr/OsB9kWbgOTa8pZSzCvGemLQT2 +YYRdZ/KE2t6MrxoDw0yoElxRbTxtvMaImckMmeUNIxFIKZMwTceJr11gGtFM7aueZr9GjZBWhGla +U3OiprIDQRWRRS15N9+nOex43lRD1OtDIYnqW30hfLXY2xZw7h4YnCT3Mqma08GZ3g+gvhgMvFYy +JI82+R3HpL4XbDdesIm84SB/tE9Gr99wSm3+k646xQbu0Sl/uptW0Sfu5tXzH6b3dP7vd1f/+vl/ +KU83eRnpzbX6uY5JzMeJZ25PLwji920S/r8m/tVrAoLLR+hPUEsBAgoACgAAAAgAFE9PRt0kH4NL +AgAAuAoAAC4AAAAAAAAAAAAAAAAAAAAAAGdvb2dsZS5jb20hc3VuZm94LmN6ITE0MjM4NzIwMDAh +MTQyMzk1ODM5OS54bWxQSwUGAAAAAAEAAQBcAAAAlwIAAAAA \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_date.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_date.eml new file mode 100644 index 000000000..5f8a6032d --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_date.eml @@ -0,0 +1,7 @@ +From: from@here.com +To: to@here.com +Subject: Nuu +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_from.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_from.eml new file mode 100644 index 000000000..e09dd9d9e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/missing_from.eml @@ -0,0 +1,7 @@ +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mixed_filename.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mixed_filename.eml new file mode 100644 index 000000000..4a353da3a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/mixed_filename.eml @@ -0,0 +1,25 @@ +Date: Fri, 02 Feb 2018 22:23:06 +0300 +To: foo@bar.com +Subject: =?windows-1251?B?0eLl5ujpIO/w4OnxLevo8fI=?= +From: =?windows-1251?B?z/Dg6fH7IHx8IM/g8PLK7uw=?= +Content-Transfer-Encoding: quoted-printable +Content-Type: multipart/mixed; + boundary="=_743251f7a933f6b30c004fcb14eabb57" +Content-Disposition: inline + +This is a message in Mime Format. If you see this, your mail reader does not support this format. + +--=_743251f7a933f6b30c004fcb14eabb57 +Content-Type: text/html; charset=windows-1251 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + + +--=_743251f7a933f6b30c004fcb14eabb57 +Content-Type: application/octet-stream +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="Price4VladDaKar.xlsx" + +UEsDBBQAAgAIAHOyQkwNlxQhWwEAAAYFAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbK2UTU7D +CwALANECAAAT1E4AAAA= +--=_743251f7a933f6b30c004fcb14eabb57-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multipart_without_body.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multipart_without_body.eml new file mode 100644 index 000000000..8f86799fe --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multipart_without_body.eml @@ -0,0 +1,110 @@ +Received: from AS8PR02MB6805.eurprd02.prod.outlook.com (2603:10a6:20b:252::8) + by PA4PR02MB7071.eurprd02.prod.outlook.com with HTTPS; Sat, 11 Mar 2023 + 08:24:33 +0000 +Received: from omef0ahNgeoJu.eurprd02.prod.outlook.com (2603:10a6:10:33c::12) + by AS8PR02MB6805.eurprd02.prod.outlook.com (2603:10a6:20b:252::8) with + Microsoft SMTP Server (version=TLS1_2, + cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.19; Sat, 11 Mar + 2023 08:24:31 +0000 +Received: from omef0ahNgeoJu.eurprd02.prod.outlook.com + ([fe80::38c0:9c40:7fc6:93a7]) by omef0ahNgeoJu.eurprd02.prod.outlook.com + ([fe80::38c0:9c40:7fc6:93a7%7]) with mapi id 15.20.6178.019; Sat, 11 Mar 2023 + 08:24:31 +0000 +From: =?iso-8859-1?Q?Foo_B=FClow_Bar?= +To: some one +Subject: This mail will not contain a body +Thread-Topic: This mail will not contain a body +Thread-Index: AdlT8uVmpHPvImbCRM6E9LODIvAcQA== +Date: Sat, 11 Mar 2023 08:24:31 +0000 +Message-ID: + +Accept-Language: da-DK, en-US +Content-Language: en-US +X-MS-Exchange-Organization-AuthAs: Internal +X-MS-Exchange-Organization-AuthMechanism: 04 +X-MS-Exchange-Organization-AuthSource: omef0ahNgeoJu.eurprd02.prod.outlook.com +X-MS-Has-Attach: +X-MS-Exchange-Organization-Network-Message-Id: + aa546a02-2b7a-4fb1-7fd4-08db220a09f1 +X-MS-Exchange-Organization-SCL: -1 +X-MS-TNEF-Correlator: +X-MS-Exchange-Organization-RecordReviewCfmType: 0 +x-ms-publictraffictype: Email +X-Microsoft-Antispam-Mailbox-Delivery: + ucf:0;jmr:0;auth:0;dest:I;ENG:(910001)(944506478)(944626604)(920097)(425001)(930097); +X-Microsoft-Antispam-Message-Info: + PeifKDwBVlQGeDu/c7oB3MKTffBwvlRIg5GJo1AiA4LroGAjwgwlg+oPfLetX9CgtbtKZy4gZnbjLCn3jJnod5ehn3Sv9gQaoH9PWkH/PIj6izaJzwlcEk81/MdprZFrORMwR7TGNqP/7ELAHw8rOH2Dmz9vGCE4cv0EwyYS3ShUhXABj4eJ17GNu1B4o53T2m9CzTgm647FRR5jpvk5xNIjQOwrhonVXMkCf2XKwF21sd/k4XLS/jX08tFJXBNyBALhsB4cG9gx2rxZYDn11SBejGFDw4eaqIQw6fYsmsyZvEoCnBkO+vK9lGIrQhRzGj7nJ41+uHVBcUYThce7P/ORpxl3GgThHyQpXQDV00JbP1aCBzm+4w8TyFiL0aOHXDhU9UKRHg3A01F+oH8IKAIaYazLCoOzbVcijSw0icNjBQsNLWa0FvfRT8y/rIvGkOB3rZpKf7ZR0g7cSlDAB3Ml2AaTbIB4ZL6QMukP/waDIObMZFmlVaAvmJzdTEdhGSLtUBFk4CNJhd6szcwaaPZxROumOGtz0sDke2iap8wRZqpdMWHVYi/trA+IESlF2G8TPzZiXs1lRDvYjNlam5r+1Ay1zlSmKTMnGbfNvsJgHkTlcgswKTlip4jGFPh6INTSDZtx9dQuDi4vbyNQiN1qVxoOPScTXzxUKVZ2PJ+8ipL2dqudLb3R2GSDHL10uQTuoIftA/Wjf67QZ629qQ== +Content-Type: multipart/alternative; + boundary="_000_omef0ahNgeoJuEB51C568ED2227A2DAABB5BB9omef0ahNgeoJueurp_" +MIME-Version: 1.0 + +--_000_omef0ahNgeoJuEB51C568ED2227A2DAABB5BB9omef0ahNgeoJueurp_ +Content-Type: text/plain; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +This mail will not contain a body + + + +--_000_omef0ahNgeoJuEB51C568ED2227A2DAABB5BB9omef0ahNgeoJueurp_ +Content-Type: text/html; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
+

This mail will not contain a bo= +dy

+

 

+
+ + + +--_000_omef0ahNgeoJuEB51C568ED2227A2DAABB5BB9omef0ahNgeoJueurp_-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_html_parts_and_attachments.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_html_parts_and_attachments.eml new file mode 100644 index 000000000..5ccbd2c33 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_html_parts_and_attachments.eml @@ -0,0 +1,203 @@ +Return-Path: +Delivered-To: to@there.com +Return-path: +Envelope-to: to@there.com +Delivery-date: Thu, 16 Feb 2023 09:19:23 +0000 +From: FromName +Content-Type: multipart/alternative; + boundary="Apple-Mail=_5382A451-FE2F-4504-9E3F-8FEB0B716E43" +Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3731.400.51.1.1\)) +Subject: multiple_html_parts_and_attachments +Date: Thu, 16 Feb 2023 10:19:02 +0100 +To: to@there.com + + + +--Apple-Mail=_5382A451-FE2F-4504-9E3F-8FEB0B716E43 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; + charset=utf-8 + +This is the first html part + +=EF=BF=BC + +This is the second html part + +=EF=BF=BC + +This is the last html part +https://www.there.com + + +--Apple-Mail=_5382A451-FE2F-4504-9E3F-8FEB0B716E43 +Content-Type: multipart/mixed; + boundary="Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE" + + +--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE +Content-Transfer-Encoding: 7bit +Content-Type: text/html; + charset=us-ascii + +This is the first html part

+--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE +Content-Disposition: inline; + filename=attachment1.pdf +Content-Type: application/pdf; + x-unix-mode=0666; + name="attachment1.pdf" +Content-Transfer-Encoding: base64 + +JVBERi0xLjMKJcTl8uXrp/Og0MTGCjMgMCBvYmoKPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xl +bmd0aCA5MyA+PgpzdHJlYW0KeAEdjDsOgCAQBXtP8U7AzwWW3sZOKmtDKExEhej9JWbamamIqFAd +G6ww3jowacEcGC1jxQm55Jby/bzbgbZ3W2v6CzPCkBJu9AxSQRBRGFKBnIvGdPVz/ABGZhatCmVu +ZHN0cmVhbQplbmRvYmoKMSAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9SZXNv +dXJjZXMgNCAwIFIgL0NvbnRlbnRzIDMgMCBSIC9NZWRpYUJveCBbMCAwIDU5NS4yNzU2IDg0MS44 +ODk4XQo+PgplbmRvYmoKNCAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL0ltYWdlQiAvSW1hZ2VD +IC9JbWFnZUkgXSAvWE9iamVjdCA8PCAvSW0xIDUgMCBSID4+ID4+CmVuZG9iago1IDAgb2JqCjw8 +IC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMTE0IC9IZWlnaHQgMjMgL0lu +dGVycG9sYXRlIHRydWUKL0NvbG9yU3BhY2UgNiAwIFIgL0ludGVudCAvUGVyY2VwdHVhbCAvQml0 +c1BlckNvbXBvbmVudCA4IC9MZW5ndGggMTUzNCAvRmlsdGVyCi9GbGF0ZURlY29kZSA+PgpzdHJl +YW0KeAHtmAlTllUUxz9CZTVN+75rmkJmZqMpVgoCoogikArhgmyhKYoKCqK4gQQoCgIBKiiEGCIg +u4CoKU1Mi/uu7fUB7CdnunPnPmLvy4Bj08s888w592z3/J9zz7kvN286/voWgb9u9Hc8PUagu2/T +Y4cOQxBwoNoXZXBvonrj0uCfLg3ui3zvjk9bUD16/MP7xh3j2Vo0z9jVhTNvd3476rerA2XdYA1l +29nHvZoGzyq3Xb+PNG1M58p556CETV9W+6pt2ILqgpR4QXVsRL4yFCIwIRnRkWMf3ZY1lG1n7xFU +jey6239i9iJASMharBT+FVXq8Hmf2icmNT47pe7+8Uc7O0cqWwgjrsHqmnbR/wlUvz7psmJLzISF +O4DFXlSLK/0xmZe0Tip25bYlCp+AuNQXptUgHRW6i3WDFbWiioDgxA39Aw4MDS6dv27tnko/ZQ6x +r2bqB5H5T01u4MNNWrJN1bygWn7IZ+qyDEKMmFesV8KUmK3sp6Zpol9s2qt+B31XpFc1Tjrz4/CZ +8SkSKDot9o/rA1QgehSiIbP20VWCEze2HR2nRLgir6Y2N++lma9Mrxoxtzguc8mfXba3TUcZQmSV +zAZPgdReVAmHSd1hD0JDDJq5X3n2XJz1tHc9i06B+xanxhksahm7Q5DyAPvI+bsfnNAGXbh/pnjI +3DOXLfVzO/J+6K7nfGoR8T79w7tIQfUB13b0H3ZvHfBxhThZnxclhkgf6hI96nlYNsDK6/6VqKGM +QwjAEeWGFvcnJzewwtcZPmdvP9f2xyY2872UK2wf8WhByg4Jh+aa7M+QWtMRE+t7c2EYVvp3v3MH +OHPqHTapkITAvL7FXXk2jrzBukQUAE7rP7UBjJhTNphfPe9MS8E5JQdLn6HhI92Q9yksmYrmxbND +qZyc0k9gOWsSV6ToXz731vWLQ1hHyhdpaR+PQmX9ZFiOADS2lB9sckGEjNSSqukA6xRUprui2q9d +cGKFs4Oy28IckRrpyKL1bS+q63KjiLJqW7S4Wr5lGSwHWXk24hpsfvksVZmYkBHmHDpoRNAccOWq +45vRiJLzI1gBN8oY0ET6+7U3qKKXfKuFFSmTV9jVWbeGBadeWJBEgZYC29g6AdHAGV+JSN5jwgpZ +PH5iLCyanAi+nYjoG9StCmSkozvRaXtRdQ4qYwPTlmdEJcfzSDfg0P16ZZC4NeIaLDrNR1zpgaPD +drJVaUGCKucFz3qX1vdJshxJfQVzJqasIH1Rk6YUhOMqbVeo0n/Gu45Nwu4oDUYEwtSzevDMYkWd +Nwq4op0qQ4jX/A6qQNZ0dE1F24WqNFI2YH2YQeLTiKuz1AwAYksTYNzMWLU5NnMprKAauWk1tPUC +LG5J1rivGqjqUkFVdwWqTEBc0U+IAoz0IuM51OyJgjUQqNKHb5udLFrfdqEakpTElpJyFjBe1SM9 +QZDBvw6jwdIwMWeHp7oGEFKGLytiu/GLSOg5a9erTX7/3XvhGxNpoaxYk+0ZqsUHbl1gmDsqCgSB +aPW/dB03a6A+rdWfL78JIPQcfl/oWzrL/HJtZwTLuqCq5pHO5pYFkZHeORelrlSoMvKgGdnqd1n4 +hjWsgHYvosrtmt3SKhlqkgW/hflAdGlpy7agqrLTcdBp22s1ryyQHLlD6uZCj4/KRZS6Mwx2afoK +aK/o7Uwig2Uc0EjJiIvK9r2zgVf6KvO39rAHyh6LsrFl4G4pCvGP/Zz7AMdWCtuabM9qlSjysbg1 +cQqyS4K5XBGUGYGIxxpIr1UjOzGxvm1HVVJmUludpO+ez8ZcwgsR8R2ZsLByrg2WwmOsIOWhuZVW ++TL4oOXqQrXI+BMFrm1c5iUc84JLux76Zd9qaZUsGlJJKrN4rtLnlkVrFZb/0oSuXysheHPFjUlf +rqat4QoTfkeoQEY6yr9BUGB45nerWr/zfVWp3ZngoKkjhqbOcikCqxMdLsoDNNdgxZ4/Pay60etk +xxg01WKvE0TkLrq/dsq508Psda6nY6Ntr6BqY6z/j5oD1b741g5U7yaq3aHtWLcXgb8Bi7W2lwpl +bmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0xl +bmd0aCAzNDMgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBdZA7SwNBFIXPxsiCpkgh +Vim2sRBWiZsgdpKoiJBiiYqPbrKJiZDHsFkRG7HzD4iVYCdprWKhIP4CQVCxshC1FwI+wnomUTaF +3uHOfHPm3N3LBUIRIWU5DKBS9dzsfNpYXVs39BeEEIWOJEzh1GXKtjO04PdUHETrFpq63Yypb8VO +P7Kv+eP9+7Q5rYvGYuD7kwbyhbrDly+m5UjXA7Q42d72pOI98pDLpsgHiotdbijOdfm841nKztBz +TY46JZEnP5LNXI9e7OFKeUv9V4XqPlKoLqteh5kxzGIOGS4DNixOYQJT1PBPTbJTM4MaJHbgYhNF +lOCxOkVFoowCeQFVOBiHSbYQZybUrFnLCGYYaLUIMPnMx6tAE0/A2e7PSAxVCYzQEz0CLt6lcEVX +4661wvWNhNW5a4NNoP/Q999WAH0UaN/5/mfT99snQN8DcNn6BsE0ZMMKZW5kc3RyZWFtCmVuZG9i +ago2IDAgb2JqClsgL0lDQ0Jhc2VkIDcgMCBSIF0KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1Bh +Z2VzIC9NZWRpYUJveCBbMCAwIDU5NS4yNzU2IDg0MS44ODk4XSAvQ291bnQgMSAvS2lkcyBbIDEg +MCBSIF0KPj4KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+ +CmVuZG9iago5IDAgb2JqCjw8IC9UaXRsZSAo/v9cMDAwU1wwMDBjXDAwMGhcMDAwZVwwMDByXDAw +MG1cMDAwrVwwMDBhXDAwMGZcMDAwYlwwMDBlXDAwMGVcMDAwbFwwMDBkXDAwMGlcMDAwblwwMDBn +XDAwMCBcMDAwMlwwMDAwXDAwMDJcMDAwM1wwMDAtXDAwMDBcMDAwMlwwMDAtXDAwMDFcMDAwNlww +MDAgXDAwMG9cMDAwbVwwMDAgXDAwMDFcMDAwMFwwMDAuXDAwMDFcMDAwMVwwMDAuXDAwMDBcMDAw +M1wwMDAuXDAwMHBcMDAwblwwMDBnKQovUHJvZHVjZXIgKG1hY09TIFZlcnNpZSAxMy4yIFwoYnVp +bGQgMjJENDlcKSBRdWFydHogUERGQ29udGV4dCkgL0NyZWF0b3IgKFZvb3J2ZXJ0b25pbmcpCi9D +cmVhdGlvbkRhdGUgKEQ6MjAyMzAyMTYwOTExNDdaMDAnMDAnKSAvTW9kRGF0ZSAoRDoyMDIzMDIx +NjA5MTE0N1owMCcwMCcpCj4+CmVuZG9iagp4cmVmCjAgMTAKMDAwMDAwMDAwMCA2NTUzNSBmIAow +MDAwMDAwMTg2IDAwMDAwIG4gCjAwMDAwMDI2MDIgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBu +IAowMDAwMDAwMzAwIDAwMDAwIG4gCjAwMDAwMDAzODkgMDAwMDAgbiAKMDAwMDAwMjU2NyAwMDAw +MCBuIAowMDAwMDAyMTI1IDAwMDAwIG4gCjAwMDAwMDI2OTUgMDAwMDAgbiAKMDAwMDAwMjc0NCAw +MDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDEwIC9Sb290IDggMCBSIC9JbmZvIDkgMCBSIC9JRCBb +IDxlNzk0OWE2YzQ2MWM1MDYxNTk0ODU5YjkxZjczYzAzMz4KPGU3OTQ5YTZjNDYxYzUwNjE1OTQ4 +NTliOTFmNzNjMDMzPiBdID4+CnN0YXJ0eHJlZgozMTYxCiUlRU9GCg== +--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE +Content-Transfer-Encoding: 7bit +Content-Type: text/html; + charset=us-ascii + +

This is the second html part

+--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE +Content-Disposition: inline; + filename=attachment2.pdf +Content-Type: application/pdf; + x-unix-mode=0666; + name="attachment2.pdf" +Content-Transfer-Encoding: base64 + +JVBERi0xLjMKJcTl8uXrp/Og0MTGCjMgMCBvYmoKPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xl +bmd0aCA5MyA+PgpzdHJlYW0KeAEdjDsOgCAQBXtP8U4ALB9Zehs7qawNoTARFaL3l5hpZ6YiokJ1 +XHBCezeCLQnmwGgZK07IJbeU7+fdDrS926TpL4yCNl6Q8QyrnAjWhiEVyLkQpquf4wdGBBarCmVu +ZHN0cmVhbQplbmRvYmoKMSAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9SZXNv +dXJjZXMgNCAwIFIgL0NvbnRlbnRzIDMgMCBSIC9NZWRpYUJveCBbMCAwIDU5NS4yNzU2IDg0MS44 +ODk4XQo+PgplbmRvYmoKNCAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL0ltYWdlQiAvSW1hZ2VD +IC9JbWFnZUkgXSAvWE9iamVjdCA8PCAvSW0xIDUgMCBSID4+ID4+CmVuZG9iago1IDAgb2JqCjw8 +IC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMTIxIC9IZWlnaHQgMzAgL0lu +dGVycG9sYXRlIHRydWUKL0NvbG9yU3BhY2UgNiAwIFIgL0ludGVudCAvUGVyY2VwdHVhbCAvQml0 +c1BlckNvbXBvbmVudCA4IC9MZW5ndGggMTczNSAvRmlsdGVyCi9GbGF0ZURlY29kZSA+PgpzdHJl +YW0KeAHtl4lT1kUYx/+Eymq677s0TTHzajSPPBFE8UA0T1RuxRMVUfEAEVECFQVREQ9UxiNFVFAU +FJAxGrDM+9bu+gPsI8+0s+27v3qFmnLm987OO8+9u9999nn2d++e+3MRcBFwEXARcBFwEXBE4Le7 +Td3RYAQcYbUpGjyL6wgCNkQdZS5ijUHAEVabojETNd737vWW311v2fg4/1UEG6KOMn2RVdU9Hul1 +mrFme6guh7568aO62s4/3WoucoM1jL1nnws43nL0Xu/t/yXLv93O+XMd0rZEjluUMjRu1ayMuZXV +PWQljrDaFPrip6xIEKi7R+fqcugxC1NRVZzuKXKDNYy9Z/8nUP/1dsjAt4IOsf0n+51kQDzue2rd +zvFs04aoo0zBQsa+Nrj4+QGlrwwqebR3VV1dJ6WCMBZjsLrlA9EPBdQ9J28C3qUbYoDo1lWflXmR +sE/7l106384RVptCIZNfOJwIoUlLJbfnr41VqhHz0l4fehht54ityA1WzLbvHxGyeFnTEQfahBSE +L03cURis3CH2HB7y6aTcFwce4zQHxK5Vt0Og3ntk8JA5q5iiY2j+wqwZynHQ7DWs5/Dx/sHx6e8E +Hwyam1FUOuDit+1HJayQiWamx/9yp5myp8ShajV6D0UpZHHKqapeSkUo9nX8VN/AWZlvDyvqODF/ +Xmbsr/W+1u0oR+AFVWIqCYTP2N2gsfNgsA1RR5mKwBpwLynzYz0QLUbtUyr/GVkvBR5F6DNmz4y0 +eQaL2aptYWgZnEWn8G3cL+i8faMkQuaOiVyTJn0rPonY+urgYlT8XzjXAS1QP9anEnsuZrPP9kuQ +5I0x4oj2iXrVM/5lsgAk7w0vxAxjAkKAmBgfK+/3wsBjSDiy9hN2NulT+Wz/ExyiCoXvU37laFmh +1IEl2dPQem5HXOS/trYzCRCbPlcJOSCQZyLyxxFWm0IiXDzfjpUreCEIdbS8n4pvVAyD7Ra9GcRO +/pFFYIs7CYb7rSutqUgEJzlhSZKxC5ejXbZxMizbF8trl9qwhZyCcbC+U9fLvKLF/sblD+9ca4Uc +LcdUXtkbg8KjA2G5LND4kqiwqZujmQLJrqJhoE366aG4F7ev+iABJYz7Ts0RrbEdETr9b9w9Bl/O +kWZqQ9RRJgEpRLgvWDtT2LjVc2CpA2o6YzEGm7t3tMphXNgm7txZaFTQ1AcVquarLqhSc6ORACYJ +D5Ki/fn2++Tbm0GHhBXtzSuthV2UNZ1QFA1hgRcDKhJs6UlfVM1HfiEq+e8amYew+kx3WCy5Oxyo +qCg7ZLiayNiOHkSneZdShVgwg3RC5QirTSGhWtcXH14yMakJDCkm3Nkfb7YQA2MxBovNiYo+1NUu +kVtYPythjwI1tRdar/wSUP5BgButS3CnNSvtG5p2xeYoQqVvjVD2LweWsEjY9QUhqICdzFeDyAj3 +lwRiwESUaOUI8W7wQTWR53Z0S6FpRlK7eI2QSyK0Ieoow0WKM6vyHMSXmMZidJbsAlV8qSGUtZEL +VsZnzoIVqCctXwTt+VCXsCBgvKsNqHWtQK2HAmpaLaEoR8wCtpQyYxw54Y+B50RATW237k6E6p+K +NCExmfjcOIo2jxClcoTVpsArLCmJOEk5U2juakhJEbiw0bE1WIow7iybd76sgdaPRHxTNk2CZqmi +4v+brz+OSllMWYb2RKBhUOcfuP98osGpWWQi2scP9RfTcyLvs3rayvkEbzt+l9QifQoboo6y7298 +AErUMYq8HoRHI22FB4DIBWrV+HR2w+6xrESvxtPT7q9NoKa3QvNgkG7FFFHLliDhCKA9EWgY1HwF +sFrKL91TdsEnP6HIQyn1nhN5Qq12p+PASRGEJ9DZs3/60BAbR1htCumnvHX1+EL3jtkAJnyQwvI1 +Ch0wc52UKZ3lrCnObJO3E99QYC61mu5fXOaHr9/0bHxp96u3hw2P/5zXCLderoAnAg2DmlnkBHnI +cV+yd4Xw3mNS+o7sxXMiHWp9O2Kv/uXO0hHYhTHoxTZEHWWCA+8EFVwRGdvCWW23qDwknDj9HVZy +1WBJUfoXWgYFs6AoiA4LLa8p8kr6rBjwkuRLRGahMRlfBzQdKb8YGFr5TMvMv9/6ZfDwo1wLzfMg +IjlRpuCfPJydEafauhEKFz6C1ETGdlR8iMScqSqmQTT4E0aP70RzT9UNxUZneacB4JmabsoXmue6 +Yq9caHuoNODLmq5YKuE/TjAjb+Z9xYMuX2j7oMH17Xjp65jBNoWXMV0zKwI2RB1l1giu0EsEHGG1 +KbyM6ZpZEbAh6spcBFwEXARcBB4aBH4HWDJl2AplbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwg +L04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0xlbmd0aCAzNDMgL0ZpbHRlciAvRmxhdGVEZWNv +ZGUgPj4Kc3RyZWFtCngBdZA7SwNBFIXPxsiCpkghVim2sRBWiZsgdpKoiJBiiYqPbrKJiZDHsFkR +G7HzD4iVYCdprWKhIP4CQVCxshC1FwI+wnomUTaF3uHOfHPm3N3LBUIRIWU5DKBS9dzsfNpYXVs3 +9BeEEIWOJEzh1GXKtjO04PdUHETrFpq63Yypb8VOP7Kv+eP9+7Q5rYvGYuD7kwbyhbrDly+m5UjX +A7Q42d72pOI98pDLpsgHiotdbijOdfm841nKztBzTY46JZEnP5LNXI9e7OFKeUv9V4XqPlKoLqte +h5kxzGIOGS4DNixOYQJT1PBPTbJTM4MaJHbgYhNFlOCxOkVFoowCeQFVOBiHSbYQZybUrFnLCGYY +aLUIMPnMx6tAE0/A2e7PSAxVCYzQEz0CLt6lcEVX4661wvWNhNW5a4NNoP/Q999WAH0UaN/5/mfT +99snQN8DcNn6BsE0ZMMKZW5kc3RyZWFtCmVuZG9iago2IDAgb2JqClsgL0lDQ0Jhc2VkIDcgMCBS +IF0KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9NZWRpYUJveCBbMCAwIDU5NS4yNzU2 +IDg0MS44ODk4XSAvQ291bnQgMSAvS2lkcyBbIDEgMCBSIF0KPj4KZW5kb2JqCjggMCBvYmoKPDwg +L1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+CmVuZG9iago5IDAgb2JqCjw8IC9UaXRsZSAo +/v9cMDAwU1wwMDBjXDAwMGhcMDAwZVwwMDByXDAwMG1cMDAwrVwwMDBhXDAwMGZcMDAwYlwwMDBl +XDAwMGVcMDAwbFwwMDBkXDAwMGlcMDAwblwwMDBnXDAwMCBcMDAwMlwwMDAwXDAwMDJcMDAwM1ww +MDAtXDAwMDBcMDAwMlwwMDAtXDAwMDFcMDAwNlwwMDAgXDAwMG9cMDAwbVwwMDAgXDAwMDFcMDAw +MFwwMDAuXDAwMDFcMDAwMVwwMDAuXDAwMDFcMDAwMFwwMDAuXDAwMHBcMDAwblwwMDBnKQovUHJv +ZHVjZXIgKG1hY09TIFZlcnNpZSAxMy4yIFwoYnVpbGQgMjJENDlcKSBRdWFydHogUERGQ29udGV4 +dCkgL0NyZWF0b3IgKFZvb3J2ZXJ0b25pbmcpCi9DcmVhdGlvbkRhdGUgKEQ6MjAyMzAyMTYwOTEx +MzhaMDAnMDAnKSAvTW9kRGF0ZSAoRDoyMDIzMDIxNjA5MTEzOFowMCcwMCcpCj4+CmVuZG9iagp4 +cmVmCjAgMTAKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMTg2IDAwMDAwIG4gCjAwMDAwMDI4 +MDMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAwMzAwIDAwMDAwIG4gCjAwMDAw +MDAzODkgMDAwMDAgbiAKMDAwMDAwMjc2OCAwMDAwMCBuIAowMDAwMDAyMzI2IDAwMDAwIG4gCjAw +MDAwMDI4OTYgMDAwMDAgbiAKMDAwMDAwMjk0NSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDEw +IC9Sb290IDggMCBSIC9JbmZvIDkgMCBSIC9JRCBbIDxjOWI4YzBlZGQ5Mjk1Y2U3ZmQ2YzFkOWJj +ZTJhZTRiOD4KPGM5YjhjMGVkZDkyOTVjZTdmZDZjMWQ5YmNlMmFlNGI4PiBdID4+CnN0YXJ0eHJl +ZgozMzYyCiUlRU9GCg== +--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE +Content-Transfer-Encoding: 7bit +Content-Type: text/html; + charset=us-ascii + +

This is the last html part
https://www.there.com



+
+--Apple-Mail=_7C42F551-D023-4101-858E-D004D27871BE-- + +--Apple-Mail=_5382A451-FE2F-4504-9E3F-8FEB0B716E43-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_nested_attachments.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_nested_attachments.eml new file mode 100644 index 000000000..ad48d47b5 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/multiple_nested_attachments.eml @@ -0,0 +1,84 @@ +Date: Mon, 15 Jan 2018 10:54:09 +0100 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 + Thunderbird/52.5.0 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------85793CE1578A77318D5A90A6" +Content-Language: en-US + +This is a multi-part message in MIME format. +--------------85793CE1578A77318D5A90A6 +Content-Type: multipart/alternative; + boundary="------------32D598A7FC3F8A8E228998B0" + + +--------------32D598A7FC3F8A8E228998B0 +Content-Type: text/plain; charset=utf-8; format=flowed +Content-Transfer-Encoding: 7bit + + +------------------------------------------------------------------------ + + + + +--------------32D598A7FC3F8A8E228998B0 +Content-Type: multipart/related; + boundary="------------261DC39B47CFCDB73BCE3C18" + + +--------------261DC39B47CFCDB73BCE3C18 +Content-Type: text/html; charset=utf-8 +Content-Transfer-Encoding: 8bit + + + + + + + +


+

+
+ + + Â +
+ + + + + + + +

+

+
+
+ + + +--------------261DC39B47CFCDB73BCE3C18 +Content-Type: image/png; + name="mleokdgdlgkkecep.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="mleokdgdlgkkecep.png" + +iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAACklE +QVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg== +--------------261DC39B47CFCDB73BCE3C18-- + +--------------32D598A7FC3F8A8E228998B0-- + +--------------85793CE1578A77318D5A90A6 +Content-Type: image/png; + name="FF4D00-1.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="FF4D00-1.png" + +iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAACklE +QVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg== +--------------85793CE1578A77318D5A90A6-- \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/nestes_embedded_with_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/nestes_embedded_with_attachment.eml new file mode 100644 index 000000000..44498103a --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/nestes_embedded_with_attachment.eml @@ -0,0 +1,145 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_000_000" + +This is a multi-part message in MIME format. + +------=_NextPart_000_000_000 +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_111_000" + + +------=_NextPart_000_111_000 +Content-Type: text/plain; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +Dear Sarah + +------=_NextPart_000_111_000 +Content-Type: text/html; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + + + +
Dear Sarah,
+ + +------=_NextPart_000_111_000-- + +------=_NextPart_000_000_000 +Content-Type: message/rfc822; + name="first.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="first.eml" + +From: from@there.com +To: to@here.com +Subject: FIRST +Date: Sat, 28 Apr 2018 14:37:16 -0400 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_222_000" + +This is a multi-part message in MIME format. + +------=_NextPart_000_222_000 +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_222_111" + + +------=_NextPart_000_222_111 +Content-Type: text/plain; + charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +Please respond directly to this email to update your RMA + + +2018-04-17T11:04:03-04:00 +------=_NextPart_000_222_111 +Content-Type: text/html; + charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + + +
Please respond directly to this = +email to=20 +update your RMA
+ +------=_NextPart_000_222_111-- + +------=_NextPart_000_222_000 +Content-Type: image/png; + name="chrome.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="chrome.png" + +iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAB+FBMVEUAAAA/mUPidDHiLi5Cn0Xk +NTPmeUrkdUg/m0Q0pEfcpSbwaVdKskg+lUP4zA/iLi3msSHkOjVAmETdJSjtYFE/lkPnRj3sWUs8 +kkLeqCVIq0fxvhXqUkbVmSjwa1n1yBLepyX1xxP0xRXqUkboST9KukpHpUbuvRrzrhF/ljbwalju +ZFM4jELaoSdLtElJrUj1xxP6zwzfqSU4i0HYnydMtUlIqUfywxb60AxZqEXaoifgMCXptR9MtklH +pEY2iUHWnSjvvRr70QujkC+pUC/90glMuEnlOjVMt0j70QriLS1LtEnnRj3qUUXfIidOjsxAhcZF +o0bjNDH0xxNLr0dIrUdmntVTkMoyfL8jcLBRuErhJyrgKyb4zA/5zg3tYFBBmUTmQTnhMinruBzv +vhnxwxZ/st+Ktt5zp9hqota2vtK6y9FemNBblc9HiMiTtMbFtsM6gcPV2r6dwroseLrMrbQrdLGd +yKoobKbo3Zh+ynrgVllZulTsXE3rV0pIqUf42UVUo0JyjEHoS0HmsiHRGR/lmRz/1hjqnxjvpRWf +wtOhusaz0LRGf7FEfbDVmqHXlJeW0pbXq5bec3fX0nTnzmuJuWvhoFFhm0FtrziBsjaAaDCYWC+u +Si6jQS3FsSfLJiTirCOkuCG1KiG+wSC+GBvgyhTszQ64Z77KAAAARXRSTlMAIQRDLyUgCwsE6ebm +5ubg2dLR0byXl4FDQzU1NDEuLSUgC+vr6urq6ubb29vb2tra2tG8vLu7u7uXl5eXgYGBgYGBLiUA +LabIAAABsElEQVQoz12S9VPjQBxHt8VaOA6HE+AOzv1wd7pJk5I2adpCC7RUcHd3d3fXf5PvLkxh +eD++z+yb7GSRlwD/+Hj/APQCZWxM5M+goF+RMbHK594v+tPoiN1uHxkt+xzt9+R9wnRTZZQpXQ0T +5uP1IQxToyOAZiQu5HEpjeA4SWIoksRxNiGC1tRZJ4LNxgHgnU5nJZBDvuDdl8lzQRBsQ+s9PZt7 +s7Pz8wsL39/DkIfZ4xlB2Gqsq62ta9oxVlVrNZpihFRpGO9fzQw1ms0NDWZz07iGkJmIFH8xxkc3 +a/WWlubmFkv9AB2SEpDvKxbjidN2faseaNV3zoHXvv7wMODJdkOHAegweAfFPx4G67KluxzottCU +9n8CUqXzcIQdXOytAHqXxomvykhEKN9EFutG22p//0rbNvHVxiJywa8yS2KDfV1dfbu31H8jF1RH +iTKtWYeHxUvq3bn0pyjCRaiRU6aDO+gb3aEfEeVNsDgm8zzLy9egPa7Qt8TSJdwhjplk06HH43ZN +J3s91KKCHQ5x4sw1fRGYDZ0n1L4FKb9/BP5JLYxToheoFCVxz57PPS8UhhEpLBVeAAAAAElFTkSu +QmCC + +------=_NextPart_000_222_000-- + +------=_NextPart_000_000_000 +Content-Type: message/rfc822; + name="second.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="second.eml" + +From: from@there.com +To: to@here.com +Subject: SECOND +Date: Sat, 28 Apr 2018 13:37:30 -0400 +MIME-Version: 1.0 +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_333_000" + +This is a multi-part message in MIME format. + +------=_NextPart_000_333_000 +Content-Type: text/plain; + charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +T whom it may concern: +------=_NextPart_000_333_000 +Content-Type: text/html; + charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + + +
T whom it may concern:
+ + +------=_NextPart_000_333_000-- + +------=_NextPart_000_000_000-- + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/null_content_charset.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/null_content_charset.eml new file mode 100644 index 000000000..0f19eb441 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/null_content_charset.eml @@ -0,0 +1,8 @@ +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +From: from@there.com +To: to@here.com + +Hi! \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/pec.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/pec.eml new file mode 100644 index 000000000..15dfacca7 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/pec.eml @@ -0,0 +1,65 @@ +To: test@example.com +From: test@example.com +Subject: Certified +Date: Mon, 2 Oct 2017 12:13:43 +0200 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="----258A05BDE519DE69AAE8D59024C32F5E" + +This is an S/MIME signed message + +------258A05BDE519DE69AAE8D59024C32F5E +Content-Type: multipart/mixed; boundary="----------=_1506939223-24530-42" +Content-Transfer-Encoding: binary + +------------=_1506939223-24530-42 +Content-Type: multipart/alternative; + boundary="----------=_1506939223-24530-43" +Content-Transfer-Encoding: binary + +------------=_1506939223-24530-43 +Content-Type: text/plain; charset="iso-8859-1" +Content-Disposition: inline +Content-Transfer-Encoding: quoted-printable + +Signed + +------------=_1506939223-24530-43 +Content-Type: text/html; charset="iso-8859-1" +Content-Disposition: inline +Content-Transfer-Encoding: quoted-printable + +Signed + +------------=_1506939223-24530-43-- + +------------=_1506939223-24530-42 +Content-Type: application/xml; name="data.xml" +Content-Disposition: inline; filename="data.xml" +Content-Transfer-Encoding: base64 + +PHhtbC8+ + +------------=_1506939223-24530-42 +Content-Type: message/rfc822; name="postacert.eml" +Content-Disposition: inline; filename="postacert.eml" +Content-Transfer-Encoding: 7bit + +To: test@example.com +From: test@example.com +Subject: test-subject +Date: Mon, 2 Oct 2017 12:13:50 +0200 +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +test-content + +------------=_1506939223-24530-42-- + +------258A05BDE519DE69AAE8D59024C32F5E +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MQ== + +------258A05BDE519DE69AAE8D59024C32F5E-- + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain.eml new file mode 100644 index 000000000..4d3d22b1d --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain.eml @@ -0,0 +1,9 @@ +From: from@someone.com +To: to@someone-else.com +Subject: Example +Date: Mon, 21 Jan 2023 19:36:45 +0200 +Content-Type: text/plain; + charset=\"us-ascii\" +Content-Transfer-Encoding: quoted-printable + +Hi there! \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_only.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_only.eml new file mode 100644 index 000000000..bbf9f3b31 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_only.eml @@ -0,0 +1,9 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_text_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_text_attachment.eml new file mode 100644 index 000000000..6ec6a6c51 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/plain_text_attachment.eml @@ -0,0 +1,21 @@ +To: to@here.com +From: from@there.com +Subject: Plain text attachment +Date: Tue, 21 Aug 2018 09:05:14 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------B832AF745285AEEC6D5AEE42" + +This is a multi-part message in MIME format. +--------------B832AF745285AEEC6D5AEE42 +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +Test +--------------B832AF745285AEEC6D5AEE42 +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="a.txt" + +SGkh +--------------B832AF745285AEEC6D5AEE42-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/references.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/references.eml new file mode 100644 index 000000000..478383cf5 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/references.eml @@ -0,0 +1,11 @@ +Message-ID: <123@example.com> +From: no_host +Cc: "This one: is \"right\"" , No-address +In-Reply-To: +References: <231d9ac57aec7d8c1a0eacfeab8af6f3@example.com> <08F04024-A5B3-4FDE-BF2C-6710DE97D8D9@example.com> +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi +How are you? diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/simple_multipart.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/simple_multipart.eml new file mode 100644 index 000000000..60a6521ce --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/simple_multipart.eml @@ -0,0 +1,23 @@ +From: from@there.com +To: to@here.com +Date: Wed, 27 Sep 2017 12:48:51 +0200 +Subject: test +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_0081_01D32C91.033E7020" + +This is a multipart message in MIME format. + +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit + +MyPlain +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/html; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +MyHtml +------=_NextPart_000_0081_01D32C91.033E7020-- + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/structured_with_attachment.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/structured_with_attachment.eml new file mode 100644 index 000000000..f795ec3af --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/structured_with_attachment.eml @@ -0,0 +1,24 @@ +From: from@there.com +To: to@here.com +Subject: Test +Date: Fri, 29 Sep 2017 10:55:23 +0200 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------5B1F217006A67C28E756A62E" + +This is a multi-part message in MIME format. +--------------5B1F217006A67C28E756A62E +Content-Type: text/plain; charset=iso-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +Test + +--------------5B1F217006A67C28E756A62E +Content-Type: text/plain; charset=UTF-8; + name="MyFile.txt" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="MyFile.txt" + +TXlGaWxlQ29udGVudA== +--------------5B1F217006A67C28E756A62E-- diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_my_topic.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_my_topic.eml new file mode 100644 index 000000000..9a1963512 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_my_topic.eml @@ -0,0 +1,10 @@ +Message-ID: <123@example.com> +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_re_my_topic.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_re_my_topic.eml new file mode 100644 index 000000000..db4fdf419 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_re_my_topic.eml @@ -0,0 +1,11 @@ +Message-ID: <456@example.com> +In-Reply-To: <123@example.com> +From: from@there.com +To: to@here.com +Subject: Re: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_unrelated.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_unrelated.eml new file mode 100644 index 000000000..e47faa810 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/thread_unrelated.eml @@ -0,0 +1,10 @@ +Message-ID: <999@example.com> +From: from@there.com +To: to@here.com +Subject: Wut +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +Hi diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undefined_charset_header.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undefined_charset_header.eml new file mode 100644 index 000000000..117a33e43 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undefined_charset_header.eml @@ -0,0 +1,20 @@ +X-Real-To: +X-Stored-In: BlaBla +Return-Path: +Received: from + by bla.bla (CommuniGate Pro RULE 6.1.13) + with RULE id 14057804; Mon, 27 Feb 2017 13:21:44 +0930 +X-Autogenerated: Mirror +Resent-From: +Resent-Date: Mon, 27 Feb 2017 13:21:44 +0930 +Message-Id: <201702270351.BGF77614@bla.bla> +From: =?X-IAS-German?B?bXlHb3Y=?= +To: sales@bla.bla +Subject: =?X-IAS-German?B?U3VibWl0IHlvdXIgdGF4IHJlZnVuZCB8IEF1c3RyYWxpYW4gVGF4YXRpb24gT2ZmaWNlLg==?= +Date: 27 Feb 2017 04:51:29 +0100 +MIME-Version: 1.0 +Content-Type: text/html; + charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +) \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients.eml new file mode 100644 index 000000000..5d33ecff2 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients.eml @@ -0,0 +1,8 @@ +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +From: from@there.com +To: "Undisclosed Recipients" <> + +Hi! diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_minus.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_minus.eml new file mode 100644 index 000000000..73f7b83f9 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_minus.eml @@ -0,0 +1,8 @@ +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +From: from@there.com +To: undisclosed-recipients:; + +Hi! diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_space.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_space.eml new file mode 100644 index 000000000..6c06cbd44 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/undisclosed_recipients_space.eml @@ -0,0 +1,8 @@ +Subject: test +MIME-Version: 1.0 +Content-Type: text/plain +Date: Wed, 27 Sep 2017 12:48:51 +0200 +From: from@there.com +To: Undisclosed recipients:; + +Hi! diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/unknown_encoding.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/unknown_encoding.eml new file mode 100644 index 000000000..271bc4e27 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/unknown_encoding.eml @@ -0,0 +1,24 @@ +From: from@there.com +To: to@here.com +Date: Wed, 27 Sep 2017 12:48:51 +0200 +Subject: test +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_0081_01D32C91.033E7020" + +This is a multipart message in MIME format. + +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/plain; + charset= +Content-Transfer-Encoding: foobar + +MyPlain + +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/html; + charset="" +Content-Transfer-Encoding: quoted-printable + +MyHtml +------=_NextPart_000_0081_01D32C91.033E7020-- + diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_plain_only.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_plain_only.eml new file mode 100644 index 000000000..bd4fe5de0 --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_plain_only.eml @@ -0,0 +1,8 @@ +From: from@there.com +To: to@here.com +Subject: Nuu +Date: Wed, 13 Sep 2017 13:05:45 +0200 +Content-Type: text/plain; charset= +Content-Transfer-Encoding: quoted-printable + +Hi \ No newline at end of file diff --git a/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_simple_multipart.eml b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_simple_multipart.eml new file mode 100644 index 000000000..d1a092d2e --- /dev/null +++ b/lam/lib/3rdParty/composer/webklex/php-imap/tests/messages/without_charset_simple_multipart.eml @@ -0,0 +1,23 @@ +From: from@there.com +To: to@here.com +Date: Wed, 27 Sep 2017 12:48:51 +0200 +Subject: test +Content-Type: multipart/alternative; + boundary="----=_NextPart_000_0081_01D32C91.033E7020" + +This is a multipart message in MIME format. + +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/plain; + charset= +Content-Transfer-Encoding: 7bit + +MyPlain +------=_NextPart_000_0081_01D32C91.033E7020 +Content-Type: text/html; + charset="" +Content-Transfer-Encoding: quoted-printable + +MyHtml +------=_NextPart_000_0081_01D32C91.033E7020-- + diff --git a/lam/lib/modules/imapAccess.inc b/lam/lib/modules/imapAccess.inc index 95d8c3a90..53a9314d7 100644 --- a/lam/lib/modules/imapAccess.inc +++ b/lam/lib/modules/imapAccess.inc @@ -940,7 +940,7 @@ class imapAccess extends baseModule { */ private function isMailboxExisting($client, string $path): bool { $list = $client->getConnection()->folders($path); - return is_array($list) && (sizeof($list) >= 1); + return ($list !== null) && is_array($list->data()) && (sizeof($list->data()) >= 1); } /** @@ -952,13 +952,19 @@ class imapAccess extends baseModule { */ private function getQuota($client, string $user): array { $user = $client->getConnection()->escapeString($user); - $quota = $client->getConnection()->requestAndResponse('GETQUOTA', array($user)); $quota_values = array(); - if (isset($quota[0][2][0]) && ($quota[0][2][0] === 'STORAGE')) { - $quota_values = array( - self::QUOTA_LIMIT => $quota[0][2][2], - self::QUOTA_USAGE => $quota[0][2][1], - ); + try { + $quota = $client->getConnection()->requestAndResponse('GETQUOTA', array($user)); + $quota = $quota->data(); + if (isset($quota[0][2][0]) && ($quota[0][2][0] === 'STORAGE')) { + $quota_values = array( + self::QUOTA_LIMIT => $quota[0][2][2], + self::QUOTA_USAGE => $quota[0][2][1], + ); + } + } + catch (Exception $e) { + logNewMessage(LOG_DEBUG, 'Unable to read quote of ' . $user . ': ' . $e->getMessage()); } return $quota_values; } @@ -975,6 +981,7 @@ class imapAccess extends baseModule { private function runSetQuotaCommand($client, string $user, string $value): void { $user = $client->getConnection()->escapeString($user); $result = $client->getConnection()->requestAndResponse('SETQUOTA', array($user, '(STORAGE ' . $value . ')')); + $result = $result->data(); if (isset($result[0][0]) && ($result[0][0] === 'OK')) { return; } @@ -994,11 +1001,12 @@ class imapAccess extends baseModule { $userEscaped = $client->getConnection()->escapeString($user); $adminUser = $client->getConnection()->escapeString($this->getAdminUser()); $result = $client->getConnection()->requestAndResponse('SETACL', array($userEscaped, $adminUser, '+c')); + $result = $result->data(); if (!isset($result[0][0]) || ($result[0][0] !== 'OK')) { throw new LAMException(null); } $result = $client->getConnection()->deleteFolder($user); - if (!$result) { + if (!$result->successful()) { throw new LAMException(null); } }