├── .github └── title.png ├── vendor ├── symfony │ ├── polyfill-php80 │ │ ├── Resources │ │ │ └── stubs │ │ │ │ ├── ValueError.php │ │ │ │ └── Stringable.php │ │ ├── bootstrap.php │ │ └── Php80.php │ ├── intl │ │ ├── Resources │ │ │ ├── bin │ │ │ │ ├── compile │ │ │ │ ├── autoload.php │ │ │ │ ├── common.php │ │ │ │ └── update-data.php │ │ │ └── stubs │ │ │ │ ├── Collator.php │ │ │ │ ├── Locale.php │ │ │ │ ├── NumberFormatter.php │ │ │ │ └── IntlDateFormatter.php │ │ ├── Exception │ │ │ ├── ResourceBundleNotFoundException.php │ │ │ ├── ExceptionInterface.php │ │ │ ├── RuntimeException.php │ │ │ ├── MissingResourceException.php │ │ │ ├── OutOfBoundsException.php │ │ │ ├── BadMethodCallException.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── MethodNotImplementedException.php │ │ │ ├── UnexpectedTypeException.php │ │ │ ├── MethodArgumentNotImplementedException.php │ │ │ ├── NotImplementedException.php │ │ │ └── MethodArgumentValueNotImplementedException.php │ │ ├── Data │ │ │ ├── Bundle │ │ │ │ ├── Writer │ │ │ │ │ ├── BundleWriterInterface.php │ │ │ │ │ ├── JsonBundleWriter.php │ │ │ │ │ ├── PhpBundleWriter.php │ │ │ │ │ └── TextBundleWriter.php │ │ │ │ ├── Compiler │ │ │ │ │ ├── BundleCompilerInterface.php │ │ │ │ │ └── GenrbCompiler.php │ │ │ │ └── Reader │ │ │ │ │ ├── BundleReaderInterface.php │ │ │ │ │ ├── BufferedBundleReader.php │ │ │ │ │ ├── PhpBundleReader.php │ │ │ │ │ ├── IntlBundleReader.php │ │ │ │ │ ├── JsonBundleReader.php │ │ │ │ │ ├── BundleEntryReaderInterface.php │ │ │ │ │ └── BundleEntryReader.php │ │ │ ├── Util │ │ │ │ ├── RecursiveArrayAccess.php │ │ │ │ ├── ArrayAccessibleResourceBundle.php │ │ │ │ ├── RingBuffer.php │ │ │ │ └── LocaleScanner.php │ │ │ └── Generator │ │ │ │ ├── FallbackTrait.php │ │ │ │ ├── GeneratorConfig.php │ │ │ │ ├── ScriptDataGenerator.php │ │ │ │ ├── AbstractDataGenerator.php │ │ │ │ ├── CurrencyDataGenerator.php │ │ │ │ ├── LocaleDataGenerator.php │ │ │ │ ├── RegionDataGenerator.php │ │ │ │ └── LanguageDataGenerator.php │ │ ├── DateFormatter │ │ │ └── DateFormat │ │ │ │ ├── HourTransformer.php │ │ │ │ ├── AmPmTransformer.php │ │ │ │ ├── DayOfYearTransformer.php │ │ │ │ ├── DayTransformer.php │ │ │ │ ├── MinuteTransformer.php │ │ │ │ ├── SecondTransformer.php │ │ │ │ ├── YearTransformer.php │ │ │ │ ├── Hour2400Transformer.php │ │ │ │ ├── Hour1200Transformer.php │ │ │ │ ├── Hour1201Transformer.php │ │ │ │ ├── Hour2401Transformer.php │ │ │ │ ├── DayOfWeekTransformer.php │ │ │ │ ├── QuarterTransformer.php │ │ │ │ ├── Transformer.php │ │ │ │ ├── MonthTransformer.php │ │ │ │ └── TimezoneTransformer.php │ │ ├── Scripts.php │ │ ├── Locales.php │ │ ├── Util │ │ │ ├── Version.php │ │ │ ├── GitRepository.php │ │ │ ├── IcuVersion.php │ │ │ └── IntlTestHelper.php │ │ ├── ResourceBundle.php │ │ ├── Globals │ │ │ └── IntlGlobals.php │ │ ├── Locale.php │ │ ├── Timezones.php │ │ ├── Intl.php │ │ ├── Currencies.php │ │ ├── Countries.php │ │ ├── Languages.php │ │ └── Collator │ │ │ └── Collator.php │ └── polyfill-intl-icu │ │ └── bootstrap.php ├── composer │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_classmap.php │ ├── platform_check.php │ ├── autoload_static.php │ ├── autoload_real.php │ └── installed.php ├── openpsa │ └── ranger │ │ └── src │ │ └── Provider │ │ ├── Provider.php │ │ ├── DefaultProvider.php │ │ └── DeProvider.php └── autoload.php ├── .editorconfig ├── rector.php ├── .gitignore ├── .prettierrc ├── LICENSE.md └── composer.json /.github/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hananils/kirby-date-methods/HEAD/.github/title.png -------------------------------------------------------------------------------- /vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/openpsa/ranger/src'), 10 | ); 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | charset = utf-8 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | max_line_length = 80 9 | 10 | [*.yml] 11 | indent_size = 2 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/bin/compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ $1 == force ]] && docker pull jakzal/php-intl 4 | [[ ! -d /tmp/symfony/icu ]] && mkdir -p /tmp/symfony/icu 5 | 6 | docker run \ 7 | -it --rm --name symfony-intl \ 8 | -u $(id -u):$(id -g) \ 9 | -v /tmp/symfony/icu:/tmp \ 10 | -v $(pwd):/symfony \ 11 | -w /symfony \ 12 | jakzal/php-intl:latest \ 13 | php src/Symfony/Component/Intl/Resources/bin/update-data.php 14 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | withSkip([ClosureToArrowFunctionRector::class]) 10 | ->withPaths([__DIR__ . '/index.php']) 11 | // uncomment to reach your current PHP version 12 | ->withPhpSets() 13 | ->withAttributesSets() 14 | ->withTypeCoverageLevel(0) 15 | ->withDeadCodeLevel(0) 16 | ->withCodeQualityLevel(0); 17 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/ResourceBundleNotFoundException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * @author Bernhard Schussek 16 | */ 17 | class ResourceBundleNotFoundException extends RuntimeException 18 | { 19 | } 20 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/bin/autoload.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | $autoload = __DIR__.'/../../vendor/autoload.php'; 13 | 14 | if (!file_exists($autoload)) { 15 | bailout('You should run "composer install" in the component before running this script.'); 16 | } 17 | 18 | require_once $autoload; 19 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Base ExceptionInterface for the Intl component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | interface ExceptionInterface extends \Throwable 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS files 2 | .DS_Store 3 | 4 | # npm modules 5 | /node_modules 6 | 7 | # files of Composer dependencies that are not needed for the plugin 8 | /vendor/**/.* 9 | /vendor/**/*.json 10 | /vendor/**/*.txt 11 | /vendor/**/*.md 12 | /vendor/**/*.yml 13 | /vendor/**/*.yaml 14 | /vendor/**/*.xml 15 | /vendor/**/*.dist 16 | /vendor/**/readme.php 17 | /vendor/**/LICENSE 18 | /vendor/**/COPYING 19 | /vendor/**/VERSION 20 | /vendor/**/docs/* 21 | /vendor/**/example/* 22 | /vendor/**/examples/* 23 | /vendor/**/test/* 24 | /vendor/**/tests/* 25 | /vendor/**/php4/* 26 | /vendor/getkirby/composer-installer -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSameLine": false, 3 | "bracketSpacing": true, 4 | "htmlWhitespaceSensitivity": "css", 5 | "phpVersion": "8.2", 6 | "printWidth": 80, 7 | "proseWrap": "never", 8 | "semi": true, 9 | "singleQuote": true, 10 | "trailingComma": "none", 11 | "trailingCommaPHP": false, 12 | "plugins": ["@prettier/plugin-php", "prettier-plugin-css-order"], 13 | "overrides": [ 14 | { 15 | "files": "LICENSE.md", 16 | "options": { 17 | "proseWrap": "always" 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * RuntimeException for the Intl component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class RuntimeException extends \RuntimeException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/stubs/Collator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Intl\Collator\Collator as IntlCollator; 13 | 14 | /** 15 | * Stub implementation for the Collator class of the intl extension. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class Collator extends IntlCollator 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/MissingResourceException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Thrown when an invalid entry of a resource bundle was requested. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class MissingResourceException extends RuntimeException 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/stubs/Locale.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Intl\Locale\Locale as IntlLocale; 13 | 14 | /** 15 | * Stub implementation for the Locale class of the intl extension. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @see IntlLocale 20 | */ 21 | class Locale extends IntlLocale 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/OutOfBoundsException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Base OutOfBoundsException for the Intl component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/BadMethodCallException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Base BadMethodCallException for the Intl component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * InvalidArgumentException for the Intl component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /vendor/openpsa/ranger/src/Provider/Provider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Intl\NumberFormatter\NumberFormatter as IntlNumberFormatter; 13 | 14 | /** 15 | * Stub implementation for the NumberFormatter class of the intl extension. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @see IntlNumberFormatter 20 | */ 21 | class NumberFormatter extends IntlNumberFormatter 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/stubs/IntlDateFormatter.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Intl\DateFormatter\IntlDateFormatter as BaseIntlDateFormatter; 13 | 14 | /** 15 | * Stub implementation for the IntlDateFormatter class of the intl extension. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @see BaseIntlDateFormatter 20 | */ 21 | class IntlDateFormatter extends BaseIntlDateFormatter 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Writer/BundleWriterInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Writer; 13 | 14 | /** 15 | * Writes resource bundle files. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | interface BundleWriterInterface 22 | { 23 | /** 24 | * Writes data to a resource bundle. 25 | * 26 | * @param mixed $data The data to write 27 | */ 28 | public function write(string $path, string $locale, $data); 29 | } 30 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Compiler/BundleCompilerInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Compiler; 13 | 14 | /** 15 | * Compiles a resource bundle. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | interface BundleCompilerInterface 22 | { 23 | /** 24 | * Compiles a resource bundle at the given source to the given target 25 | * directory. 26 | */ 27 | public function compile(string $sourcePath, string $targetDir); 28 | } 29 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/MethodNotImplementedException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * @author Eriksen Costa 16 | */ 17 | class MethodNotImplementedException extends NotImplementedException 18 | { 19 | /** 20 | * @param string $methodName The name of the method 21 | */ 22 | public function __construct(string $methodName) 23 | { 24 | parent::__construct(sprintf('The %s() is not implemented.', $methodName)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/BundleReaderInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | /** 15 | * Reads resource bundle files. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | interface BundleReaderInterface 22 | { 23 | /** 24 | * @return mixed returns an array or {@link \ArrayAccess} instance for 25 | * complex data, a scalar value otherwise 26 | */ 27 | public function read(string $path, string $locale); 28 | } 29 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/UnexpectedTypeException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Thrown when a method argument had an unexpected type. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class UnexpectedTypeException extends InvalidArgumentException 20 | { 21 | public function __construct($value, string $expectedType) 22 | { 23 | parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, get_debug_type($value))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/openpsa/ranger/src/Provider/DefaultProvider.php: -------------------------------------------------------------------------------- 1 | getDateType() < IntlDateFormatter::MEDIUM) { 21 | return ' ' . trim($separator) . ' '; 22 | } 23 | return $separator; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/autoload.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Intl\Globals\IntlGlobals; 13 | 14 | if (!function_exists('intl_is_failure')) { 15 | function intl_is_failure($errorCode) { return IntlGlobals::isFailure($errorCode); } 16 | } 17 | if (!function_exists('intl_get_error_code')) { 18 | function intl_get_error_code() { return IntlGlobals::getErrorCode(); } 19 | } 20 | if (!function_exists('intl_get_error_message')) { 21 | function intl_get_error_message() { return IntlGlobals::getErrorMessage(); } 22 | } 23 | if (!function_exists('intl_error_name')) { 24 | function intl_error_name($errorCode) { return IntlGlobals::getErrorName($errorCode); } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/HourTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Base class for hour transformers. 16 | * 17 | * @author Eriksen Costa 18 | * 19 | * @internal 20 | */ 21 | abstract class HourTransformer extends Transformer 22 | { 23 | /** 24 | * Returns a normalized hour value suitable for the hour transformer type. 25 | * 26 | * @param int $hour The hour value 27 | * @param string $marker An optional AM/PM marker 28 | * 29 | * @return int The normalized hour value 30 | */ 31 | abstract public function normalizeHour(int $hour, string $marker = null): int; 32 | } 33 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/MethodArgumentNotImplementedException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * @author Eriksen Costa 16 | */ 17 | class MethodArgumentNotImplementedException extends NotImplementedException 18 | { 19 | /** 20 | * @param string $methodName The method name that raised the exception 21 | * @param string $argName The argument name that is not implemented 22 | */ 23 | public function __construct(string $methodName, string $argName) 24 | { 25 | $message = sprintf('The %s() method\'s argument $%s behavior is not implemented.', $methodName, $argName); 26 | parent::__construct($message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 80200)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/NotImplementedException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * Base exception class for not implemented behaviors of the intl extension in the Locale component. 16 | * 17 | * @author Eriksen Costa 18 | */ 19 | class NotImplementedException extends RuntimeException 20 | { 21 | const INTL_INSTALL_MESSAGE = 'Please install the "intl" extension for full localization capabilities.'; 22 | 23 | /** 24 | * @param string $message The exception message. A note to install the intl extension is appended to this string 25 | */ 26 | public function __construct(string $message) 27 | { 28 | parent::__construct($message.' '.self::INTL_INSTALL_MESSAGE); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/openpsa/ranger/src/Provider/DeProvider.php: -------------------------------------------------------------------------------- 1 | Ranger::MONTH 21 | || $intl->getDateType() < IntlDateFormatter::MEDIUM) { 22 | $separator = ' ' . trim($separator) . ' '; 23 | } 24 | if ( $best_match == Ranger::MONTH 25 | || ( $intl->getDateType() > IntlDateFormatter::LONG 26 | && $best_match == Ranger::YEAR)) { 27 | return '.' . $separator; 28 | } 29 | return $separator; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) hana+nils · Büro für Gestaltung 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/AmPmTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for AM/PM markers format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class AmPmTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | return $dateTime->format('A'); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function getReverseMatchingRegExp(int $length): string 35 | { 36 | return 'AM|PM'; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function extractDateOptions(string $matched, int $length): array 43 | { 44 | return [ 45 | 'marker' => $matched, 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hananils/kirby-date-methods", 3 | "description": "Parsing and formatting dates can be difficult, especially if you deal with multilingual content. Date Methods aims to simplify date output by providing page and field methods to handle points in time as well as date ranges accurately in your snippets and templates.", 4 | "license": "MIT", 5 | "type": "kirby-plugin", 6 | "version": "3.0.0", 7 | "authors": [ 8 | { 9 | "name": "hana+nils · Büro für Gestaltung", 10 | "email": "buero@hananils.de" 11 | } 12 | ], 13 | "homepage": "https://kirby.hananils.de/plugins/date-methods", 14 | "require": { 15 | "php": "^8.2", 16 | "openpsa/ranger": "^0.5.1" 17 | }, 18 | "require-dev": { 19 | "ergebnis/composer-normalize": "^2.47", 20 | "rector/rector": "^2.0" 21 | }, 22 | "replace": { 23 | "symfony/intl": "*" 24 | }, 25 | "suggest": { 26 | "symfony/intl": "~2.6|~3.4|~4.0|~5.0|~6.0|~7.0" 27 | }, 28 | "config": { 29 | "allow-plugins": { 30 | "ergebnis/composer-normalize": true 31 | }, 32 | "sort-packages": true 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Writer/JsonBundleWriter.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Writer; 13 | 14 | /** 15 | * Writes .json resource bundles. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | class JsonBundleWriter implements BundleWriterInterface 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function write(string $path, string $locale, $data) 27 | { 28 | if ($data instanceof \Traversable) { 29 | $data = iterator_to_array($data); 30 | } 31 | 32 | array_walk_recursive($data, function (&$value) { 33 | if ($value instanceof \Traversable) { 34 | $value = iterator_to_array($value); 35 | } 36 | }); 37 | 38 | $contents = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)."\n"; 39 | 40 | file_put_contents($path.'/'.$locale.'.json', $contents); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | 11 | array ( 12 | 'OpenPsa\\Ranger\\' => 15, 13 | ), 14 | ); 15 | 16 | public static $prefixDirsPsr4 = array ( 17 | 'OpenPsa\\Ranger\\' => 18 | array ( 19 | 0 => __DIR__ . '/..' . '/openpsa/ranger/src', 20 | ), 21 | ); 22 | 23 | public static $classMap = array ( 24 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 25 | ); 26 | 27 | public static function getInitializer(ClassLoader $loader) 28 | { 29 | return \Closure::bind(function () use ($loader) { 30 | $loader->prefixLengthsPsr4 = ComposerStaticInit8353d4e334a9604aa595127a111bced4::$prefixLengthsPsr4; 31 | $loader->prefixDirsPsr4 = ComposerStaticInit8353d4e334a9604aa595127a111bced4::$prefixDirsPsr4; 32 | $loader->classMap = ComposerStaticInit8353d4e334a9604aa595127a111bced4::$classMap; 33 | 34 | }, null, ClassLoader::class); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/DayOfYearTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for day of year format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class DayOfYearTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $dayOfYear = (int) $dateTime->format('z') + 1; 29 | 30 | return $this->padLeft($dayOfYear, $length); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getReverseMatchingRegExp(int $length): string 37 | { 38 | return '\d{'.$length.'}'; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function extractDateOptions(string $matched, int $length): array 45 | { 46 | return []; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/DayTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for day format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class DayTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | return $this->padLeft($dateTime->format('j'), $length); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function getReverseMatchingRegExp(int $length): string 35 | { 36 | return 1 === $length ? '\d{1,2}' : '\d{1,'.$length.'}'; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function extractDateOptions(string $matched, int $length): array 43 | { 44 | return [ 45 | 'day' => (int) $matched, 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | register(true); 35 | 36 | return $loader; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/MinuteTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for minute format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class MinuteTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $minuteOfHour = (int) $dateTime->format('i'); 29 | 30 | return $this->padLeft($minuteOfHour, $length); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getReverseMatchingRegExp(int $length): string 37 | { 38 | return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}'; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function extractDateOptions(string $matched, int $length): array 45 | { 46 | return [ 47 | 'minute' => (int) $matched, 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/SecondTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for the second format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class SecondTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $secondOfMinute = (int) $dateTime->format('s'); 29 | 30 | return $this->padLeft($secondOfMinute, $length); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getReverseMatchingRegExp(int $length): string 37 | { 38 | return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}'; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function extractDateOptions(string $matched, int $length): array 45 | { 46 | return [ 47 | 'second' => (int) $matched, 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/YearTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for year format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class YearTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | if (2 === $length) { 29 | return $dateTime->format('y'); 30 | } 31 | 32 | return $this->padLeft($dateTime->format('Y'), $length); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function getReverseMatchingRegExp(int $length): string 39 | { 40 | return 2 === $length ? '\d{2}' : '\d{1,4}'; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function extractDateOptions(string $matched, int $length): array 47 | { 48 | return [ 49 | 'year' => (int) $matched, 50 | ]; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | array( 3 | 'name' => 'hananils/kirby-date-methods', 4 | 'pretty_version' => '2.1.0', 5 | 'version' => '2.1.0.0', 6 | 'reference' => null, 7 | 'type' => 'kirby-plugin', 8 | 'install_path' => __DIR__ . '/../../', 9 | 'aliases' => array(), 10 | 'dev' => false, 11 | ), 12 | 'versions' => array( 13 | 'hananils/kirby-date-methods' => array( 14 | 'pretty_version' => '2.1.0', 15 | 'version' => '2.1.0.0', 16 | 'reference' => null, 17 | 'type' => 'kirby-plugin', 18 | 'install_path' => __DIR__ . '/../../', 19 | 'aliases' => array(), 20 | 'dev_requirement' => false, 21 | ), 22 | 'openpsa/ranger' => array( 23 | 'pretty_version' => 'v0.5.8.1', 24 | 'version' => '0.5.8.1', 25 | 'reference' => '6896106f1a5e74a672beb0fadc41615c8ff6d1bb', 26 | 'type' => 'library', 27 | 'install_path' => __DIR__ . '/../openpsa/ranger', 28 | 'aliases' => array(), 29 | 'dev_requirement' => false, 30 | ), 31 | 'symfony/intl' => array( 32 | 'dev_requirement' => false, 33 | 'replaced' => array( 34 | 0 => '*', 35 | ), 36 | ), 37 | ), 38 | ); 39 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/BufferedBundleReader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Data\Util\RingBuffer; 15 | 16 | /** 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | class BufferedBundleReader implements BundleReaderInterface 22 | { 23 | private $reader; 24 | private $buffer; 25 | 26 | /** 27 | * Buffers a given reader. 28 | * 29 | * @param int $bufferSize The number of entries to store in the buffer 30 | */ 31 | public function __construct(BundleReaderInterface $reader, int $bufferSize) 32 | { 33 | $this->reader = $reader; 34 | $this->buffer = new RingBuffer($bufferSize); 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function read(string $path, string $locale) 41 | { 42 | $hash = $path.'//'.$locale; 43 | 44 | if (!isset($this->buffer[$hash])) { 45 | $this->buffer[$hash] = $this->reader->read($path, $locale); 46 | } 47 | 48 | return $this->buffer[$hash]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Util/RecursiveArrayAccess.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Util; 13 | 14 | use Symfony\Component\Intl\Exception\OutOfBoundsException; 15 | 16 | /** 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | class RecursiveArrayAccess 22 | { 23 | public static function get($array, array $indices) 24 | { 25 | foreach ($indices as $index) { 26 | // Use array_key_exists() for arrays, isset() otherwise 27 | if (\is_array($array)) { 28 | if (\array_key_exists($index, $array)) { 29 | $array = $array[$index]; 30 | continue; 31 | } 32 | } elseif ($array instanceof \ArrayAccess) { 33 | if (isset($array[$index])) { 34 | $array = $array[$index]; 35 | continue; 36 | } 37 | } 38 | 39 | throw new OutOfBoundsException(sprintf('The index "%s" does not exist.', $index)); 40 | } 41 | 42 | return $array; 43 | } 44 | 45 | private function __construct() 46 | { 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Exception/MethodArgumentValueNotImplementedException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Exception; 13 | 14 | /** 15 | * @author Eriksen Costa 16 | */ 17 | class MethodArgumentValueNotImplementedException extends NotImplementedException 18 | { 19 | /** 20 | * @param string $methodName The method name that raised the exception 21 | * @param string $argName The argument name 22 | * @param mixed $argValue The argument value that is not implemented 23 | * @param string $additionalMessage An optional additional message to append to the exception message 24 | */ 25 | public function __construct(string $methodName, string $argName, $argValue, string $additionalMessage = '') 26 | { 27 | $message = sprintf( 28 | 'The %s() method\'s argument $%s value %s behavior is not implemented.%s', 29 | $methodName, 30 | $argName, 31 | var_export($argValue, true), 32 | '' !== $additionalMessage ? ' '.$additionalMessage.'. ' : '' 33 | ); 34 | 35 | parent::__construct($message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/PhpBundleReader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException; 15 | use Symfony\Component\Intl\Exception\RuntimeException; 16 | 17 | /** 18 | * Reads .php resource bundles. 19 | * 20 | * @author Bernhard Schussek 21 | * 22 | * @internal 23 | */ 24 | class PhpBundleReader implements BundleReaderInterface 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function read(string $path, string $locale) 30 | { 31 | $fileName = $path.'/'.$locale.'.php'; 32 | 33 | // prevent directory traversal attacks 34 | if (\dirname($fileName) !== $path) { 35 | throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName)); 36 | } 37 | 38 | if (!file_exists($fileName)) { 39 | throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s/%s.php" does not exist.', $path, $locale)); 40 | } 41 | 42 | if (!is_file($fileName)) { 43 | throw new RuntimeException(sprintf('The resource bundle "%s/%s.php" is not a file.', $path, $locale)); 44 | } 45 | 46 | return include $fileName; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Writer/PhpBundleWriter.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Writer; 13 | 14 | /** 15 | * Writes .php resource bundles. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | class PhpBundleWriter implements BundleWriterInterface 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function write(string $path, string $locale, $data) 27 | { 28 | $template = <<<'TEMPLATE' 29 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for 24 hour format (0-23). 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class Hour2400Transformer extends HourTransformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | return $this->padLeft($dateTime->format('G'), $length); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function normalizeHour(int $hour, string $marker = null): int 35 | { 36 | if ('AM' === $marker) { 37 | $hour = 0; 38 | } elseif ('PM' === $marker) { 39 | $hour = 12; 40 | } 41 | 42 | return $hour; 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function getReverseMatchingRegExp(int $length): string 49 | { 50 | return '\d{1,2}'; 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function extractDateOptions(string $matched, int $length): array 57 | { 58 | return [ 59 | 'hour' => (int) $matched, 60 | 'hourInstance' => $this, 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/Hour1200Transformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for 12 hour format (0-11). 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class Hour1200Transformer extends HourTransformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $hourOfDay = $dateTime->format('g'); 29 | $hourOfDay = '12' === $hourOfDay ? '0' : $hourOfDay; 30 | 31 | return $this->padLeft($hourOfDay, $length); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function normalizeHour(int $hour, string $marker = null): int 38 | { 39 | if ('PM' === $marker) { 40 | $hour += 12; 41 | } 42 | 43 | return $hour; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function getReverseMatchingRegExp(int $length): string 50 | { 51 | return '\d{1,2}'; 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function extractDateOptions(string $matched, int $length): array 58 | { 59 | return [ 60 | 'hour' => (int) $matched, 61 | 'hourInstance' => $this, 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-php80/bootstrap.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Polyfill\Php80 as p; 13 | 14 | if (PHP_VERSION_ID >= 80000) { 15 | return; 16 | } 17 | 18 | if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { 19 | define('FILTER_VALIDATE_BOOL', FILTER_VALIDATE_BOOLEAN); 20 | } 21 | 22 | if (!function_exists('fdiv')) { 23 | function fdiv(float $dividend, float $divisor): float { return p\Php80::fdiv($dividend, $divisor); } 24 | } 25 | if (!function_exists('preg_last_error_msg')) { 26 | function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } 27 | } 28 | if (!function_exists('str_contains')) { 29 | function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); } 30 | } 31 | if (!function_exists('str_starts_with')) { 32 | function str_starts_with(string $haystack, string $needle): bool { return p\Php80::str_starts_with($haystack, $needle); } 33 | } 34 | if (!function_exists('str_ends_with')) { 35 | function str_ends_with(string $haystack, string $needle): bool { return p\Php80::str_ends_with($haystack, $needle); } 36 | } 37 | if (!function_exists('get_debug_type')) { 38 | function get_debug_type($value): string { return p\Php80::get_debug_type($value); } 39 | } 40 | if (!function_exists('get_resource_id')) { 41 | function get_resource_id($res): int { return p\Php80::get_resource_id($res); } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/Hour1201Transformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for 12 hour format (1-12). 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class Hour1201Transformer extends HourTransformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | return $this->padLeft($dateTime->format('g'), $length); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function normalizeHour(int $hour, string $marker = null): int 35 | { 36 | if ('PM' !== $marker && 12 === $hour) { 37 | $hour = 0; 38 | } elseif ('PM' === $marker && 12 !== $hour) { 39 | // If PM and hour is not 12 (1-12), sum 12 hour 40 | $hour += 12; 41 | } 42 | 43 | return $hour; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function getReverseMatchingRegExp(int $length): string 50 | { 51 | return '\d{1,2}'; 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function extractDateOptions(string $matched, int $length): array 58 | { 59 | return [ 60 | 'hour' => (int) $matched, 61 | 'hourInstance' => $this, 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/Hour2401Transformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for 24 hour format (1-24). 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class Hour2401Transformer extends HourTransformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $hourOfDay = $dateTime->format('G'); 29 | $hourOfDay = '0' === $hourOfDay ? '24' : $hourOfDay; 30 | 31 | return $this->padLeft($hourOfDay, $length); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function normalizeHour(int $hour, string $marker = null): int 38 | { 39 | if ((null === $marker && 24 === $hour) || 'AM' === $marker) { 40 | $hour = 0; 41 | } elseif ('PM' === $marker) { 42 | $hour = 12; 43 | } 44 | 45 | return $hour; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function getReverseMatchingRegExp(int $length): string 52 | { 53 | return '\d{1,2}'; 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function extractDateOptions(string $matched, int $length): array 60 | { 61 | return [ 62 | 'hour' => (int) $matched, 63 | 'hourInstance' => $this, 64 | ]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/IntlBundleReader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle; 15 | use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException; 16 | 17 | /** 18 | * Reads binary .res resource bundles. 19 | * 20 | * @author Bernhard Schussek 21 | * 22 | * @internal 23 | */ 24 | class IntlBundleReader implements BundleReaderInterface 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function read(string $path, string $locale) 30 | { 31 | // Point for future extension: Modify this class so that it works also 32 | // if the \ResourceBundle class is not available. 33 | try { 34 | // Never enable fallback. We want to know if a bundle cannot be found 35 | $bundle = new \ResourceBundle($locale, $path, false); 36 | } catch (\Exception $e) { 37 | $bundle = null; 38 | } 39 | 40 | // The bundle is NULL if the path does not look like a resource bundle 41 | // (i.e. contain a bunch of *.res files) 42 | if (null === $bundle) { 43 | throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s/%s.res" could not be found.', $path, $locale)); 44 | } 45 | 46 | // Other possible errors are U_USING_FALLBACK_WARNING and U_ZERO_ERROR, 47 | // which are OK for us. 48 | return new ArrayAccessibleResourceBundle($bundle); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/JsonBundleReader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException; 15 | use Symfony\Component\Intl\Exception\RuntimeException; 16 | 17 | /** 18 | * Reads .json resource bundles. 19 | * 20 | * @author Bernhard Schussek 21 | * 22 | * @internal 23 | */ 24 | class JsonBundleReader implements BundleReaderInterface 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function read(string $path, string $locale) 30 | { 31 | $fileName = $path.'/'.$locale.'.json'; 32 | 33 | // prevent directory traversal attacks 34 | if (\dirname($fileName) !== $path) { 35 | throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName)); 36 | } 37 | 38 | if (!file_exists($fileName)) { 39 | throw new ResourceBundleNotFoundException(sprintf('The resource bundle "%s" does not exist.', $fileName)); 40 | } 41 | 42 | if (!is_file($fileName)) { 43 | throw new RuntimeException(sprintf('The resource bundle "%s" is not a file.', $fileName)); 44 | } 45 | 46 | $data = json_decode(file_get_contents($fileName), true); 47 | 48 | if (null === $data) { 49 | throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: ', $fileName).json_last_error_msg()); 50 | } 51 | 52 | return $data; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Scripts.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Gives access to script-related ICU data. 18 | * 19 | * @author Bernhard Schussek 20 | * @author Roland Franssen 21 | */ 22 | final class Scripts extends ResourceBundle 23 | { 24 | /** 25 | * @return string[] 26 | */ 27 | public static function getScriptCodes(): array 28 | { 29 | return self::readEntry(['Scripts'], 'meta'); 30 | } 31 | 32 | public static function exists(string $script): bool 33 | { 34 | try { 35 | self::readEntry(['Names', $script]); 36 | 37 | return true; 38 | } catch (MissingResourceException $e) { 39 | return false; 40 | } 41 | } 42 | 43 | /** 44 | * @throws MissingResourceException if the script code does not exist 45 | */ 46 | public static function getName(string $script, string $displayLocale = null): string 47 | { 48 | return self::readEntry(['Names', $script], $displayLocale); 49 | } 50 | 51 | /** 52 | * @return string[] 53 | */ 54 | public static function getNames($displayLocale = null): array 55 | { 56 | return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale); 57 | } 58 | 59 | protected static function getPath(): string 60 | { 61 | return Intl::getDataDirectory().'/'.Intl::SCRIPT_DIR; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/DayOfWeekTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for day of week format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class DayOfWeekTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $dayOfWeek = $dateTime->format('l'); 29 | switch ($length) { 30 | case 4: 31 | return $dayOfWeek; 32 | case 5: 33 | return $dayOfWeek[0]; 34 | case 6: 35 | return substr($dayOfWeek, 0, 2); 36 | default: 37 | return substr($dayOfWeek, 0, 3); 38 | } 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function getReverseMatchingRegExp(int $length): string 45 | { 46 | switch ($length) { 47 | case 4: 48 | return 'Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday'; 49 | case 5: 50 | return '[MTWFS]'; 51 | case 6: 52 | return 'Mo|Tu|We|Th|Fr|Sa|Su'; 53 | default: 54 | return 'Mon|Tue|Wed|Thu|Fri|Sat|Sun'; 55 | } 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function extractDateOptions(string $matched, int $length): array 62 | { 63 | return []; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/QuarterTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for quarter format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class QuarterTransformer extends Transformer 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function format(\DateTime $dateTime, int $length): string 27 | { 28 | $month = (int) $dateTime->format('n'); 29 | $quarter = (int) floor(($month - 1) / 3) + 1; 30 | switch ($length) { 31 | case 1: 32 | case 2: 33 | return $this->padLeft($quarter, $length); 34 | case 3: 35 | return 'Q'.$quarter; 36 | default: 37 | $map = [1 => '1st quarter', 2 => '2nd quarter', 3 => '3rd quarter', 4 => '4th quarter']; 38 | 39 | return $map[$quarter]; 40 | } 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function getReverseMatchingRegExp(int $length): string 47 | { 48 | switch ($length) { 49 | case 1: 50 | case 2: 51 | return '\d{'.$length.'}'; 52 | case 3: 53 | return 'Q\d'; 54 | default: 55 | return '(?:1st|2nd|3rd|4th) quarter'; 56 | } 57 | } 58 | 59 | /** 60 | * {@inheritdoc} 61 | */ 62 | public function extractDateOptions(string $matched, int $length): array 63 | { 64 | return []; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Compiler/GenrbCompiler.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Compiler; 13 | 14 | use Symfony\Component\Intl\Exception\RuntimeException; 15 | 16 | /** 17 | * Compiles .txt resource bundles to binary .res files. 18 | * 19 | * @author Bernhard Schussek 20 | * 21 | * @internal 22 | */ 23 | class GenrbCompiler implements BundleCompilerInterface 24 | { 25 | private $genrb; 26 | 27 | /** 28 | * Creates a new compiler based on the "genrb" executable. 29 | * 30 | * @param string $genrb Optional. The path to the "genrb" executable 31 | * @param string $envVars Optional. Environment variables to be loaded when running "genrb". 32 | * 33 | * @throws RuntimeException if the "genrb" cannot be found 34 | */ 35 | public function __construct(string $genrb = 'genrb', string $envVars = '') 36 | { 37 | exec('which '.$genrb, $output, $status); 38 | 39 | if (0 !== $status) { 40 | throw new RuntimeException(sprintf('The command "%s" is not installed.', $genrb)); 41 | } 42 | 43 | $this->genrb = ($envVars ? $envVars.' ' : '').$genrb; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function compile(string $sourcePath, string $targetDir) 50 | { 51 | if (is_dir($sourcePath)) { 52 | $sourcePath .= '/*.txt'; 53 | } 54 | 55 | exec($this->genrb.' --quiet -e UTF-8 -d '.$targetDir.' '.$sourcePath, $output, $status); 56 | 57 | if (0 !== $status) { 58 | throw new RuntimeException(sprintf('genrb failed with status %d while compiling "%s" to "%s".', $status, $sourcePath, $targetDir)); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/FallbackTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 15 | use Symfony\Component\Intl\Locale; 16 | 17 | /** 18 | * @author Roland Franssen 19 | * 20 | * @internal 21 | */ 22 | trait FallbackTrait 23 | { 24 | private $fallbackCache = []; 25 | private $generatingFallback = false; 26 | 27 | /** 28 | * @see AbstractDataGenerator::generateDataForLocale() 29 | */ 30 | abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array; 31 | 32 | /** 33 | * @see AbstractDataGenerator::generateDataForRoot() 34 | */ 35 | abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array; 36 | 37 | private function generateFallbackData(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): array 38 | { 39 | if (null === $fallback = Locale::getFallback($displayLocale)) { 40 | return []; 41 | } 42 | 43 | if (isset($this->fallbackCache[$fallback])) { 44 | return $this->fallbackCache[$fallback]; 45 | } 46 | 47 | $prevGeneratingFallback = $this->generatingFallback; 48 | $this->generatingFallback = true; 49 | 50 | try { 51 | $data = 'root' === $fallback ? $this->generateDataForRoot($reader, $tempDir) : $this->generateDataForLocale($reader, $tempDir, $fallback); 52 | } finally { 53 | $this->generatingFallback = $prevGeneratingFallback; 54 | } 55 | 56 | return $this->fallbackCache[$fallback] = $data ?: []; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/GeneratorConfig.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Writer\BundleWriterInterface; 15 | 16 | /** 17 | * Stores contextual information for resource bundle generation. 18 | * 19 | * @author Bernhard Schussek 20 | * 21 | * @internal 22 | */ 23 | class GeneratorConfig 24 | { 25 | private $sourceDir; 26 | private $icuVersion; 27 | 28 | /** 29 | * @var BundleWriterInterface[] 30 | */ 31 | private $bundleWriters = []; 32 | 33 | public function __construct(string $sourceDir, string $icuVersion) 34 | { 35 | $this->sourceDir = $sourceDir; 36 | $this->icuVersion = $icuVersion; 37 | } 38 | 39 | /** 40 | * Adds a writer to be used during the data conversion. 41 | */ 42 | public function addBundleWriter(string $targetDir, BundleWriterInterface $writer) 43 | { 44 | $this->bundleWriters[$targetDir] = $writer; 45 | } 46 | 47 | /** 48 | * Returns the writers indexed by their output directories. 49 | * 50 | * @return BundleWriterInterface[] 51 | */ 52 | public function getBundleWriters(): array 53 | { 54 | return $this->bundleWriters; 55 | } 56 | 57 | /** 58 | * Returns the directory where the source versions of the resource bundles 59 | * are stored. 60 | * 61 | * @return string An absolute path to a directory 62 | */ 63 | public function getSourceDir(): string 64 | { 65 | return $this->sourceDir; 66 | } 67 | 68 | /** 69 | * Returns the ICU version of the bundles being converted. 70 | * 71 | * @return string The ICU version string 72 | */ 73 | public function getIcuVersion(): string 74 | { 75 | return $this->icuVersion; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReaderInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Reads individual entries of a resource file. 18 | * 19 | * @author Bernhard Schussek 20 | * 21 | * @internal 22 | */ 23 | interface BundleEntryReaderInterface extends BundleReaderInterface 24 | { 25 | /** 26 | * Reads an entry from a resource bundle. 27 | * 28 | * An entry can be selected from the resource bundle by passing the path 29 | * to that entry in the bundle. For example, if the bundle is structured 30 | * like this: 31 | * 32 | * TopLevel 33 | * NestedLevel 34 | * Entry: Value 35 | * 36 | * Then the value can be read by calling: 37 | * 38 | * $reader->readEntry('...', 'en', ['TopLevel', 'NestedLevel', 'Entry']); 39 | * 40 | * @param string $path The path to the resource bundle 41 | * @param string[] $indices The indices to read from the bundle 42 | * @param bool $fallback Whether to merge the value with the value from 43 | * the fallback locale (e.g. "en" for "en_GB"). 44 | * Only applicable if the result is multivalued 45 | * (i.e. array or \ArrayAccess) or cannot be found 46 | * in the requested locale. 47 | * 48 | * @return mixed returns an array or {@link \ArrayAccess} instance for 49 | * complex data and a scalar value for simple data 50 | * 51 | * @throws MissingResourceException If the indices cannot be accessed 52 | */ 53 | public function readEntry(string $path, string $locale, array $indices, bool $fallback = true); 54 | } 55 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/Transformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for date formats. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | abstract class Transformer 22 | { 23 | /** 24 | * Format a value using a configured DateTime as date/time source. 25 | * 26 | * @param \DateTime $dateTime A DateTime object to be used to generate the formatted value 27 | * @param int $length The formatted value string length 28 | * 29 | * @return string The formatted value 30 | */ 31 | abstract public function format(\DateTime $dateTime, int $length): string; 32 | 33 | /** 34 | * Returns a reverse matching regular expression of a string generated by format(). 35 | * 36 | * @param int $length The length of the value to be reverse matched 37 | * 38 | * @return string The reverse matching regular expression 39 | */ 40 | abstract public function getReverseMatchingRegExp(int $length): string; 41 | 42 | /** 43 | * Extract date options from a matched value returned by the processing of the reverse matching 44 | * regular expression. 45 | * 46 | * @param string $matched The matched value 47 | * @param int $length The length of the Transformer pattern string 48 | * 49 | * @return array An associative array 50 | */ 51 | abstract public function extractDateOptions(string $matched, int $length): array; 52 | 53 | /** 54 | * Pad a string with zeros to the left. 55 | * 56 | * @param string $value The string to be padded 57 | * @param int $length The length to pad 58 | * 59 | * @return string The padded string 60 | */ 61 | protected function padLeft(string $value, int $length): string 62 | { 63 | return str_pad($value, $length, '0', STR_PAD_LEFT); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Util/ArrayAccessibleResourceBundle.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Util; 13 | 14 | use Symfony\Component\Intl\Exception\BadMethodCallException; 15 | 16 | /** 17 | * Work-around for a bug in PHP's \ResourceBundle implementation. 18 | * 19 | * More information can be found on https://bugs.php.net/64356. 20 | * This class can be removed once that bug is fixed. 21 | * 22 | * @author Bernhard Schussek 23 | * 24 | * @internal 25 | */ 26 | class ArrayAccessibleResourceBundle implements \ArrayAccess, \IteratorAggregate, \Countable 27 | { 28 | private $bundleImpl; 29 | 30 | public function __construct(\ResourceBundle $bundleImpl) 31 | { 32 | $this->bundleImpl = $bundleImpl; 33 | } 34 | 35 | public function get($offset) 36 | { 37 | $value = $this->bundleImpl->get($offset); 38 | 39 | return $value instanceof \ResourceBundle ? new static($value) : $value; 40 | } 41 | 42 | public function offsetExists($offset): bool 43 | { 44 | return null !== $this->bundleImpl->get($offset); 45 | } 46 | 47 | public function offsetGet($offset) 48 | { 49 | return $this->get($offset); 50 | } 51 | 52 | public function offsetSet($offset, $value) 53 | { 54 | throw new BadMethodCallException('Resource bundles cannot be modified.'); 55 | } 56 | 57 | public function offsetUnset($offset) 58 | { 59 | throw new BadMethodCallException('Resource bundles cannot be modified.'); 60 | } 61 | 62 | public function getIterator(): \Traversable 63 | { 64 | return $this->bundleImpl; 65 | } 66 | 67 | public function count(): int 68 | { 69 | return $this->bundleImpl->count(); 70 | } 71 | 72 | public function getErrorCode() 73 | { 74 | return $this->bundleImpl->getErrorCode(); 75 | } 76 | 77 | public function getErrorMessage() 78 | { 79 | return $this->bundleImpl->getErrorMessage(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Util/RingBuffer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Util; 13 | 14 | use Symfony\Component\Intl\Exception\OutOfBoundsException; 15 | 16 | /** 17 | * Implements a ring buffer. 18 | * 19 | * A ring buffer is an array-like structure with a fixed size. If the buffer 20 | * is full, the next written element overwrites the first bucket in the buffer, 21 | * then the second and so on. 22 | * 23 | * @author Bernhard Schussek 24 | * 25 | * @internal 26 | */ 27 | class RingBuffer implements \ArrayAccess 28 | { 29 | private $values = []; 30 | 31 | private $indices = []; 32 | 33 | private $cursor = 0; 34 | 35 | private $size; 36 | 37 | public function __construct(int $size) 38 | { 39 | $this->size = $size; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function offsetExists($key): bool 46 | { 47 | return isset($this->indices[$key]); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function offsetGet($key) 54 | { 55 | if (!isset($this->indices[$key])) { 56 | throw new OutOfBoundsException(sprintf('The index "%s" does not exist.', $key)); 57 | } 58 | 59 | return $this->values[$this->indices[$key]]; 60 | } 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | public function offsetSet($key, $value) 66 | { 67 | if (false !== ($keyToRemove = array_search($this->cursor, $this->indices))) { 68 | unset($this->indices[$keyToRemove]); 69 | } 70 | 71 | $this->values[$this->cursor] = $value; 72 | $this->indices[$key] = $this->cursor; 73 | 74 | $this->cursor = ($this->cursor + 1) % $this->size; 75 | } 76 | 77 | /** 78 | * {@inheritdoc} 79 | */ 80 | public function offsetUnset($key) 81 | { 82 | if (isset($this->indices[$key])) { 83 | $this->values[$this->indices[$key]] = null; 84 | unset($this->indices[$key]); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Locales.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Gives access to locale-related ICU data. 18 | * 19 | * @author Bernhard Schussek 20 | * @author Roland Franssen 21 | */ 22 | final class Locales extends ResourceBundle 23 | { 24 | /** 25 | * @return string[] 26 | */ 27 | public static function getLocales(): array 28 | { 29 | return self::readEntry(['Locales'], 'meta'); 30 | } 31 | 32 | /** 33 | * @return string[] 34 | */ 35 | public static function getAliases(): array 36 | { 37 | return self::readEntry(['Aliases'], 'meta'); 38 | } 39 | 40 | public static function exists(string $locale): bool 41 | { 42 | try { 43 | self::readEntry(['Names', $locale]); 44 | 45 | return true; 46 | } catch (MissingResourceException $e) { 47 | return \in_array($locale, self::getAliases(), true); 48 | } 49 | } 50 | 51 | /** 52 | * @throws MissingResourceException if the locale does not exist 53 | */ 54 | public static function getName(string $locale, string $displayLocale = null): string 55 | { 56 | try { 57 | return self::readEntry(['Names', $locale], $displayLocale); 58 | } catch (MissingResourceException $e) { 59 | if (false === $aliased = array_search($locale, self::getAliases(), true)) { 60 | throw $e; 61 | } 62 | 63 | return self::readEntry(['Names', $aliased], $displayLocale); 64 | } 65 | } 66 | 67 | /** 68 | * @return string[] 69 | */ 70 | public static function getNames($displayLocale = null): array 71 | { 72 | return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale); 73 | } 74 | 75 | protected static function getPath(): string 76 | { 77 | return Intl::getDataDirectory().'/'.Intl::LOCALE_DIR; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/bin/common.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | define('LINE_WIDTH', 75); 13 | 14 | define('LINE', str_repeat('-', LINE_WIDTH)."\n"); 15 | 16 | function bailout($message) 17 | { 18 | echo wordwrap($message, LINE_WIDTH)." Aborting.\n"; 19 | 20 | exit(1); 21 | } 22 | 23 | function strip_minor_versions($version) 24 | { 25 | preg_match('/^(?P[0-9]\.[0-9]|[0-9]{2,})/', $version, $matches); 26 | 27 | return $matches['version']; 28 | } 29 | 30 | function centered($text) 31 | { 32 | $padding = (int) ((LINE_WIDTH - strlen($text)) / 2); 33 | 34 | return str_repeat(' ', $padding).$text; 35 | } 36 | 37 | function cd($dir) 38 | { 39 | if (false === chdir($dir)) { 40 | bailout("Could not switch to directory $dir."); 41 | } 42 | } 43 | 44 | function run($command) 45 | { 46 | exec($command, $output, $status); 47 | 48 | if (0 !== $status) { 49 | $output = implode("\n", $output); 50 | echo "Error while running:\n ".getcwd().'$ '.$command."\nOutput:\n".LINE."$output\n".LINE; 51 | 52 | bailout("\"$command\" failed."); 53 | } 54 | } 55 | 56 | function get_icu_version_from_genrb($genrb) 57 | { 58 | exec($genrb.' --version - 2>&1', $output, $status); 59 | 60 | if (0 !== $status) { 61 | bailout($genrb.' failed.'); 62 | } 63 | 64 | if (!preg_match('/ICU version ([\d\.]+)/', implode('', $output), $matches)) { 65 | return null; 66 | } 67 | 68 | return $matches[1]; 69 | } 70 | 71 | error_reporting(E_ALL); 72 | 73 | set_error_handler(function ($type, $msg, $file, $line) { 74 | throw new \ErrorException($msg, 0, $type, $file, $line); 75 | }); 76 | 77 | set_exception_handler(function (\Throwable $exception) { 78 | echo "\n"; 79 | 80 | $cause = $exception; 81 | $root = true; 82 | 83 | while (null !== $cause) { 84 | if (!$root) { 85 | echo "Caused by\n"; 86 | } 87 | 88 | echo get_class($cause).': '.$cause->getMessage()."\n"; 89 | echo "\n"; 90 | echo $cause->getFile().':'.$cause->getLine()."\n"; 91 | echo $cause->getTraceAsString()."\n"; 92 | 93 | $cause = $cause->getPrevious(); 94 | $root = false; 95 | } 96 | }); 97 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Util/Version.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Util; 13 | 14 | /** 15 | * Facilitates the comparison of version strings. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class Version 20 | { 21 | /** 22 | * Compares two versions with an operator. 23 | * 24 | * This method is identical to {@link version_compare()}, except that you 25 | * can pass the number of regarded version components in the last argument 26 | * $precision. 27 | * 28 | * Examples: 29 | * 30 | * Version::compare('1.2.3', '1.2.4', '==') 31 | * // => false 32 | * 33 | * Version::compare('1.2.3', '1.2.4', '==', 2) 34 | * // => true 35 | * 36 | * @param int|null $precision The number of components to compare. Pass 37 | * NULL to compare the versions unchanged. 38 | * 39 | * @return bool Whether the comparison succeeded 40 | * 41 | * @see normalize() 42 | */ 43 | public static function compare(string $version1, string $version2, string $operator, ?int $precision = null) 44 | { 45 | $version1 = self::normalize($version1, $precision); 46 | $version2 = self::normalize($version2, $precision); 47 | 48 | return version_compare($version1, $version2, $operator); 49 | } 50 | 51 | /** 52 | * Normalizes a version string to the number of components given in the 53 | * parameter $precision. 54 | * 55 | * Examples: 56 | * 57 | * Version::normalize('1.2.3', 1); 58 | * // => '1' 59 | * 60 | * Version::normalize('1.2.3', 2); 61 | * // => '1.2' 62 | * 63 | * @param int|null $precision The number of components to include. Pass 64 | * NULL to return the version unchanged. 65 | * 66 | * @return string|null the normalized version or NULL if it couldn't be 67 | * normalized 68 | */ 69 | public static function normalize(string $version, ?int $precision) 70 | { 71 | if (null === $precision) { 72 | return $version; 73 | } 74 | 75 | $pattern = '[^\.]+'; 76 | 77 | for ($i = 2; $i <= $precision; ++$i) { 78 | $pattern = sprintf('[^\.]+(\.%s)?', $pattern); 79 | } 80 | 81 | if (!preg_match('/^'.$pattern.'/', $version, $matches)) { 82 | return null; 83 | } 84 | 85 | return $matches[0]; 86 | } 87 | 88 | /** 89 | * Must not be instantiated. 90 | */ 91 | private function __construct() 92 | { 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /vendor/symfony/intl/ResourceBundle.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Reader\BufferedBundleReader; 15 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReader; 16 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 17 | use Symfony\Component\Intl\Data\Bundle\Reader\JsonBundleReader; 18 | 19 | /** 20 | * @author Roland Franssen 21 | * 22 | * @internal 23 | */ 24 | abstract class ResourceBundle 25 | { 26 | private static $entryReader; 27 | 28 | abstract protected static function getPath(): string; 29 | 30 | /** 31 | * Reads an entry from a resource bundle. 32 | * 33 | * @see BundleEntryReaderInterface::readEntry() 34 | * 35 | * @param string[] $indices The indices to read from the bundle 36 | * @param string $locale The locale to read 37 | * @param bool $fallback Whether to merge the value with the value from 38 | * the fallback locale (e.g. "en" for "en_GB"). 39 | * Only applicable if the result is multivalued 40 | * (i.e. array or \ArrayAccess) or cannot be found 41 | * in the requested locale. 42 | * 43 | * @return mixed returns an array or {@link \ArrayAccess} instance for 44 | * complex data and a scalar value for simple data 45 | */ 46 | final protected static function readEntry(array $indices, string $locale = null, bool $fallback = true) 47 | { 48 | if (null === self::$entryReader) { 49 | self::$entryReader = new BundleEntryReader(new BufferedBundleReader( 50 | new JsonBundleReader(), 51 | Intl::BUFFER_SIZE 52 | )); 53 | 54 | $localeAliases = self::$entryReader->readEntry(Intl::getDataDirectory().'/'.Intl::LOCALE_DIR, 'meta', ['Aliases']); 55 | self::$entryReader->setLocaleAliases($localeAliases instanceof \Traversable ? iterator_to_array($localeAliases) : $localeAliases); 56 | } 57 | 58 | return self::$entryReader->readEntry(static::getPath(), $locale ?? \Locale::getDefault(), $indices, $fallback); 59 | } 60 | 61 | final protected static function asort(iterable $list, string $locale = null): array 62 | { 63 | if ($list instanceof \Traversable) { 64 | $list = iterator_to_array($list); 65 | } 66 | 67 | $collator = new \Collator($locale ?? \Locale::getDefault()); 68 | $collator->asort($list); 69 | 70 | return $list; 71 | } 72 | 73 | private function __construct() 74 | { 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/ScriptDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 15 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 16 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 17 | 18 | /** 19 | * The rule for compiling the script bundle. 20 | * 21 | * @author Bernhard Schussek 22 | * 23 | * @internal 24 | */ 25 | class ScriptDataGenerator extends AbstractDataGenerator 26 | { 27 | private static $blacklist = [ 28 | 'Zzzz' => true, // Unknown Script 29 | ]; 30 | 31 | /** 32 | * Collects all available language codes. 33 | * 34 | * @var string[] 35 | */ 36 | private $scriptCodes = []; 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array 42 | { 43 | return $scanner->scanLocales($sourceDir.'/lang'); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir) 50 | { 51 | $compiler->compile($sourceDir.'/lang', $tempDir); 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | protected function preGenerate() 58 | { 59 | $this->scriptCodes = []; 60 | } 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array 66 | { 67 | $localeBundle = $reader->read($tempDir, $displayLocale); 68 | 69 | // isset() on \ResourceBundle returns true even if the value is null 70 | if (isset($localeBundle['Scripts']) && null !== $localeBundle['Scripts']) { 71 | $data = [ 72 | 'Names' => array_diff_key(iterator_to_array($localeBundle['Scripts']), self::$blacklist), 73 | ]; 74 | 75 | $this->scriptCodes = array_merge($this->scriptCodes, array_keys($data['Names'])); 76 | 77 | return $data; 78 | } 79 | 80 | return null; 81 | } 82 | 83 | /** 84 | * {@inheritdoc} 85 | */ 86 | protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array 87 | { 88 | return null; 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | */ 94 | protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array 95 | { 96 | $this->scriptCodes = array_unique($this->scriptCodes); 97 | 98 | sort($this->scriptCodes); 99 | 100 | return [ 101 | 'Scripts' => $this->scriptCodes, 102 | ]; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Util/GitRepository.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Util; 13 | 14 | use Symfony\Component\Filesystem\Filesystem; 15 | use Symfony\Component\Intl\Exception\RuntimeException; 16 | 17 | /** 18 | * @internal 19 | */ 20 | final class GitRepository 21 | { 22 | private $path; 23 | 24 | public function __construct(string $path) 25 | { 26 | $this->path = $path; 27 | 28 | $this->getUrl(); 29 | } 30 | 31 | public static function download(string $remote, string $targetDir): self 32 | { 33 | self::exec('which git', 'The command "git" is not installed.'); 34 | 35 | $filesystem = new Filesystem(); 36 | 37 | if (!$filesystem->exists($targetDir.'/.git')) { 38 | $filesystem->remove($targetDir); 39 | $filesystem->mkdir($targetDir); 40 | 41 | self::exec(sprintf('git clone %s %s', escapeshellarg($remote), escapeshellarg($targetDir))); 42 | } 43 | 44 | return new self(realpath($targetDir)); 45 | } 46 | 47 | public function getPath(): string 48 | { 49 | return $this->path; 50 | } 51 | 52 | public function getUrl(): string 53 | { 54 | return $this->getLastLine($this->execInPath('git config --get remote.origin.url')); 55 | } 56 | 57 | public function getLastCommitHash(): string 58 | { 59 | return $this->getLastLine($this->execInPath('git log -1 --format="%H"')); 60 | } 61 | 62 | public function getLastAuthor(): string 63 | { 64 | return $this->getLastLine($this->execInPath('git log -1 --format="%an"')); 65 | } 66 | 67 | public function getLastAuthoredDate(): \DateTime 68 | { 69 | return new \DateTime($this->getLastLine($this->execInPath('git log -1 --format="%ai"'))); 70 | } 71 | 72 | public function getLastTag(callable $filter = null): string 73 | { 74 | $tags = $this->execInPath('git tag -l --sort=v:refname'); 75 | 76 | if (null !== $filter) { 77 | $tags = array_filter($tags, $filter); 78 | } 79 | 80 | return $this->getLastLine($tags); 81 | } 82 | 83 | public function checkout(string $branch) 84 | { 85 | $this->execInPath(sprintf('git checkout %s', escapeshellarg($branch))); 86 | } 87 | 88 | private function execInPath(string $command): array 89 | { 90 | return self::exec(sprintf('cd %s && %s', escapeshellarg($this->path), $command)); 91 | } 92 | 93 | private static function exec(string $command, string $customErrorMessage = null): array 94 | { 95 | exec(sprintf('%s 2>&1', $command), $output, $result); 96 | 97 | if (0 !== $result) { 98 | throw new RuntimeException(null !== $customErrorMessage ? $customErrorMessage : sprintf('The "%s" command failed.', $command)); 99 | } 100 | 101 | return $output; 102 | } 103 | 104 | private function getLastLine(array $output): string 105 | { 106 | return array_pop($output); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Util/LocaleScanner.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Util; 13 | 14 | /** 15 | * Scans a directory with data files for locales. 16 | * 17 | * The name of each file with the extension ".txt" is considered, if it "looks" 18 | * like a locale: 19 | * 20 | * - the name must start with two letters; 21 | * - the two letters may optionally be followed by an underscore and any 22 | * sequence of other symbols. 23 | * 24 | * For example, "de" and "de_DE" are considered to be locales. "root" and "meta" 25 | * are not. 26 | * 27 | * @author Bernhard Schussek 28 | * 29 | * @internal 30 | */ 31 | class LocaleScanner 32 | { 33 | /** 34 | * Returns all locales found in the given directory. 35 | * 36 | * @return array An array of locales. The result also contains locales that 37 | * are in fact just aliases for other locales. Use 38 | * {@link scanAliases()} to determine which of the locales 39 | * are aliases 40 | */ 41 | public function scanLocales(string $sourceDir): array 42 | { 43 | $locales = glob($sourceDir.'/*.txt', GLOB_NOSORT); 44 | 45 | // Remove file extension and sort 46 | array_walk($locales, function (&$locale) { $locale = basename($locale, '.txt'); }); 47 | 48 | // Remove non-locales 49 | $locales = array_filter($locales, function ($locale) { 50 | return preg_match('/^[a-z]{2}(_.+)?$/', $locale); 51 | }); 52 | 53 | sort($locales); 54 | 55 | return $locales; 56 | } 57 | 58 | /** 59 | * Returns all locale aliases found in the given directory. 60 | * 61 | * @return array An array with the locale aliases as keys and the aliased 62 | * locales as values 63 | */ 64 | public function scanAliases(string $sourceDir): array 65 | { 66 | $locales = $this->scanLocales($sourceDir); 67 | $aliases = []; 68 | 69 | // Delete locales that are no aliases 70 | foreach ($locales as $locale) { 71 | $content = file_get_contents($sourceDir.'/'.$locale.'.txt'); 72 | 73 | // Aliases contain the text "%%ALIAS" followed by the aliased locale 74 | if (preg_match('/"%%ALIAS"\{"([^"]+)"\}/', $content, $matches)) { 75 | $aliases[$locale] = $matches[1]; 76 | } 77 | } 78 | 79 | return $aliases; 80 | } 81 | 82 | /** 83 | * Returns all locale parents found in the given directory. 84 | */ 85 | public function scanParents(string $sourceDir): array 86 | { 87 | $locales = $this->scanLocales($sourceDir); 88 | $fallbacks = []; 89 | 90 | foreach ($locales as $locale) { 91 | $content = file_get_contents($sourceDir.'/'.$locale.'.txt'); 92 | 93 | // Aliases contain the text "%%PARENT" followed by the aliased locale 94 | if (preg_match('/%%Parent{"([^"]+)"}/', $content, $matches)) { 95 | $fallbacks[$locale] = $matches[1]; 96 | } 97 | } 98 | 99 | return $fallbacks; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Util/IcuVersion.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Util; 13 | 14 | /** 15 | * Facilitates the comparison of ICU version strings. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class IcuVersion 20 | { 21 | /** 22 | * Compares two ICU versions with an operator. 23 | * 24 | * This method is identical to {@link version_compare()}, except that you 25 | * can pass the number of regarded version components in the last argument 26 | * $precision. 27 | * 28 | * Also, a single digit release version and a single digit major version 29 | * are contracted to a two digit release version. If no major version 30 | * is given, it is substituted by zero. 31 | * 32 | * Examples: 33 | * 34 | * IcuVersion::compare('1.2.3', '1.2.4', '==') 35 | * // => false 36 | * 37 | * IcuVersion::compare('1.2.3', '1.2.4', '==', 2) 38 | * // => true 39 | * 40 | * IcuVersion::compare('1.2.3', '12.3', '==') 41 | * // => true 42 | * 43 | * IcuVersion::compare('1', '10', '==') 44 | * // => true 45 | * 46 | * @param int|null $precision The number of components to compare. Pass 47 | * NULL to compare the versions unchanged. 48 | * 49 | * @return bool Whether the comparison succeeded 50 | * 51 | * @see normalize() 52 | */ 53 | public static function compare(string $version1, string $version2, string $operator, ?int $precision = null) 54 | { 55 | $version1 = self::normalize($version1, $precision); 56 | $version2 = self::normalize($version2, $precision); 57 | 58 | return version_compare($version1, $version2, $operator); 59 | } 60 | 61 | /** 62 | * Normalizes a version string to the number of components given in the 63 | * parameter $precision. 64 | * 65 | * A single digit release version and a single digit major version are 66 | * contracted to a two digit release version. If no major version is given, 67 | * it is substituted by zero. 68 | * 69 | * Examples: 70 | * 71 | * IcuVersion::normalize('1.2.3.4'); 72 | * // => '12.3.4' 73 | * 74 | * IcuVersion::normalize('1.2.3.4', 1); 75 | * // => '12' 76 | * 77 | * IcuVersion::normalize('1.2.3.4', 2); 78 | * // => '12.3' 79 | * 80 | * @param int|null $precision The number of components to include. Pass 81 | * NULL to return the version unchanged. 82 | * 83 | * @return string|null the normalized ICU version or NULL if it couldn't be 84 | * normalized 85 | */ 86 | public static function normalize(string $version, ?int $precision) 87 | { 88 | $version = preg_replace('/^(\d)\.(\d)/', '$1$2', $version); 89 | 90 | if (1 === \strlen($version)) { 91 | $version .= '0'; 92 | } 93 | 94 | return Version::normalize($version, $precision); 95 | } 96 | 97 | /** 98 | * Must not be instantiated. 99 | */ 100 | private function __construct() 101 | { 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Globals/IntlGlobals.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Globals; 13 | 14 | /** 15 | * Provides fake static versions of the global functions in the intl extension. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | abstract class IntlGlobals 22 | { 23 | /** 24 | * Indicates that no error occurred. 25 | */ 26 | const U_ZERO_ERROR = 0; 27 | 28 | /** 29 | * Indicates that an invalid argument was passed. 30 | */ 31 | const U_ILLEGAL_ARGUMENT_ERROR = 1; 32 | 33 | /** 34 | * Indicates that the parse() operation failed. 35 | */ 36 | const U_PARSE_ERROR = 9; 37 | 38 | /** 39 | * All known error codes. 40 | */ 41 | private static $errorCodes = [ 42 | self::U_ZERO_ERROR => 'U_ZERO_ERROR', 43 | self::U_ILLEGAL_ARGUMENT_ERROR => 'U_ILLEGAL_ARGUMENT_ERROR', 44 | self::U_PARSE_ERROR => 'U_PARSE_ERROR', 45 | ]; 46 | 47 | /** 48 | * The error code of the last operation. 49 | */ 50 | private static $errorCode = self::U_ZERO_ERROR; 51 | 52 | /** 53 | * The error code of the last operation. 54 | */ 55 | private static $errorMessage = 'U_ZERO_ERROR'; 56 | 57 | /** 58 | * Returns whether the error code indicates a failure. 59 | * 60 | * @param int $errorCode The error code returned by IntlGlobals::getErrorCode() 61 | */ 62 | public static function isFailure(int $errorCode): bool 63 | { 64 | return isset(self::$errorCodes[$errorCode]) 65 | && $errorCode > self::U_ZERO_ERROR; 66 | } 67 | 68 | /** 69 | * Returns the error code of the last operation. 70 | * 71 | * Returns IntlGlobals::U_ZERO_ERROR if no error occurred. 72 | * 73 | * @return int 74 | */ 75 | public static function getErrorCode() 76 | { 77 | return self::$errorCode; 78 | } 79 | 80 | /** 81 | * Returns the error message of the last operation. 82 | * 83 | * Returns "U_ZERO_ERROR" if no error occurred. 84 | */ 85 | public static function getErrorMessage(): string 86 | { 87 | return self::$errorMessage; 88 | } 89 | 90 | /** 91 | * Returns the symbolic name for a given error code. 92 | * 93 | * @param int $code The error code returned by IntlGlobals::getErrorCode() 94 | */ 95 | public static function getErrorName(int $code): string 96 | { 97 | return self::$errorCodes[$code] ?? '[BOGUS UErrorCode]'; 98 | } 99 | 100 | /** 101 | * Sets the current error. 102 | * 103 | * @param int $code One of the error constants in this class 104 | * @param string $message The ICU class error message 105 | * 106 | * @throws \InvalidArgumentException If the code is not one of the error constants in this class 107 | */ 108 | public static function setError(int $code, string $message = '') 109 | { 110 | if (!isset(self::$errorCodes[$code])) { 111 | throw new \InvalidArgumentException(sprintf('No such error code: "%s".', $code)); 112 | } 113 | 114 | self::$errorMessage = $message ? sprintf('%s: %s', $message, self::$errorCodes[$code]) : self::$errorCodes[$code]; 115 | self::$errorCode = $code; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Locale.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | /** 15 | * Provides access to locale-related data. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | final class Locale extends \Locale 22 | { 23 | /** 24 | * @var string|null 25 | */ 26 | private static $defaultFallback = 'en'; 27 | 28 | /** 29 | * Sets the default fallback locale. 30 | * 31 | * The default fallback locale is used as fallback for locales that have no 32 | * fallback otherwise. 33 | * 34 | * @param string|null $locale The default fallback locale 35 | * 36 | * @see getFallback() 37 | */ 38 | public static function setDefaultFallback(?string $locale) 39 | { 40 | self::$defaultFallback = $locale; 41 | } 42 | 43 | /** 44 | * Returns the default fallback locale. 45 | * 46 | * @return string|null The default fallback locale 47 | * 48 | * @see setDefaultFallback() 49 | * @see getFallback() 50 | */ 51 | public static function getDefaultFallback(): ?string 52 | { 53 | return self::$defaultFallback; 54 | } 55 | 56 | /** 57 | * Returns the fallback locale for a given locale. 58 | * 59 | * For example, the fallback of "fr_FR" is "fr". The fallback of "fr" is 60 | * the default fallback locale configured with {@link setDefaultFallback()}. 61 | * The default fallback locale has no fallback. 62 | * 63 | * @return string|null The ICU locale code of the fallback locale, or null 64 | * if no fallback exists 65 | */ 66 | public static function getFallback(string $locale): ?string 67 | { 68 | if (\function_exists('locale_parse')) { 69 | $localeSubTags = locale_parse($locale); 70 | if (1 === \count($localeSubTags)) { 71 | if ('root' !== self::$defaultFallback && self::$defaultFallback === $localeSubTags['language']) { 72 | return 'root'; 73 | } 74 | 75 | // Don't return default fallback for "root", "meta" or others 76 | // Normal locales have two or three letters 77 | if (\strlen($locale) < 4) { 78 | return self::$defaultFallback; 79 | } 80 | 81 | return null; 82 | } 83 | 84 | array_pop($localeSubTags); 85 | 86 | $fallback = locale_compose($localeSubTags); 87 | 88 | return false !== $fallback ? $fallback : null; 89 | } 90 | 91 | if (false !== $pos = strrpos($locale, '_')) { 92 | return substr($locale, 0, $pos); 93 | } 94 | 95 | if (false !== $pos = strrpos($locale, '-')) { 96 | return substr($locale, 0, $pos); 97 | } 98 | 99 | if ('root' !== self::$defaultFallback && self::$defaultFallback === $locale) { 100 | return 'root'; 101 | } 102 | 103 | // Don't return default fallback for "root", "meta" or others 104 | // Normal locales have two or three letters 105 | return \strlen($locale) < 4 ? self::$defaultFallback : null; 106 | } 107 | 108 | /** 109 | * This class must not be instantiated. 110 | */ 111 | private function __construct() 112 | { 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-php80/Php80.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Polyfill\Php80; 13 | 14 | /** 15 | * @author Ion Bazan 16 | * @author Nico Oelgart 17 | * @author Nicolas Grekas 18 | * 19 | * @internal 20 | */ 21 | final class Php80 22 | { 23 | public static function fdiv(float $dividend, float $divisor): float 24 | { 25 | return @($dividend / $divisor); 26 | } 27 | 28 | public static function get_debug_type($value): string 29 | { 30 | switch (true) { 31 | case null === $value: return 'null'; 32 | case \is_bool($value): return 'bool'; 33 | case \is_string($value): return 'string'; 34 | case \is_array($value): return 'array'; 35 | case \is_int($value): return 'int'; 36 | case \is_float($value): return 'float'; 37 | case \is_object($value): break; 38 | case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; 39 | default: 40 | if (null === $type = @get_resource_type($value)) { 41 | return 'unknown'; 42 | } 43 | 44 | if ('Unknown' === $type) { 45 | $type = 'closed'; 46 | } 47 | 48 | return "resource ($type)"; 49 | } 50 | 51 | $class = \get_class($value); 52 | 53 | if (false === strpos($class, '@')) { 54 | return $class; 55 | } 56 | 57 | return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; 58 | } 59 | 60 | public static function get_resource_id($res): int 61 | { 62 | if (!\is_resource($res) && null === @get_resource_type($res)) { 63 | throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); 64 | } 65 | 66 | return (int) $res; 67 | } 68 | 69 | public static function preg_last_error_msg(): string 70 | { 71 | switch (preg_last_error()) { 72 | case PREG_INTERNAL_ERROR: 73 | return 'Internal error'; 74 | case PREG_BAD_UTF8_ERROR: 75 | return 'Malformed UTF-8 characters, possibly incorrectly encoded'; 76 | case PREG_BAD_UTF8_OFFSET_ERROR: 77 | return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; 78 | case PREG_BACKTRACK_LIMIT_ERROR: 79 | return 'Backtrack limit exhausted'; 80 | case PREG_RECURSION_LIMIT_ERROR: 81 | return 'Recursion limit exhausted'; 82 | case PREG_JIT_STACKLIMIT_ERROR: 83 | return 'JIT stack limit exhausted'; 84 | case PREG_NO_ERROR: 85 | return 'No error'; 86 | default: 87 | return 'Unknown error'; 88 | } 89 | } 90 | 91 | public static function str_contains(string $haystack, string $needle): bool 92 | { 93 | return '' === $needle || false !== strpos($haystack, $needle); 94 | } 95 | 96 | public static function str_starts_with(string $haystack, string $needle): bool 97 | { 98 | return 0 === \strncmp($haystack, $needle, \strlen($needle)); 99 | } 100 | 101 | public static function str_ends_with(string $haystack, string $needle): bool 102 | { 103 | return '' === $needle || ('' !== $haystack && 0 === \substr_compare($haystack, $needle, -\strlen($needle))); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/MonthTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | /** 15 | * Parser and formatter for month format. 16 | * 17 | * @author Igor Wiedler 18 | * 19 | * @internal 20 | */ 21 | class MonthTransformer extends Transformer 22 | { 23 | protected static $months = [ 24 | 'January', 25 | 'February', 26 | 'March', 27 | 'April', 28 | 'May', 29 | 'June', 30 | 'July', 31 | 'August', 32 | 'September', 33 | 'October', 34 | 'November', 35 | 'December', 36 | ]; 37 | 38 | /** 39 | * Short months names (first 3 letters). 40 | */ 41 | protected static $shortMonths = []; 42 | 43 | /** 44 | * Flipped $months array, $name => $index. 45 | */ 46 | protected static $flippedMonths = []; 47 | 48 | /** 49 | * Flipped $shortMonths array, $name => $index. 50 | */ 51 | protected static $flippedShortMonths = []; 52 | 53 | public function __construct() 54 | { 55 | if (0 === \count(self::$shortMonths)) { 56 | self::$shortMonths = array_map(function ($month) { 57 | return substr($month, 0, 3); 58 | }, self::$months); 59 | 60 | self::$flippedMonths = array_flip(self::$months); 61 | self::$flippedShortMonths = array_flip(self::$shortMonths); 62 | } 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | public function format(\DateTime $dateTime, int $length): string 69 | { 70 | $matchLengthMap = [ 71 | 1 => 'n', 72 | 2 => 'm', 73 | 3 => 'M', 74 | 4 => 'F', 75 | ]; 76 | 77 | if (isset($matchLengthMap[$length])) { 78 | return $dateTime->format($matchLengthMap[$length]); 79 | } 80 | 81 | if (5 === $length) { 82 | return substr($dateTime->format('M'), 0, 1); 83 | } 84 | 85 | return $this->padLeft($dateTime->format('m'), $length); 86 | } 87 | 88 | /** 89 | * {@inheritdoc} 90 | */ 91 | public function getReverseMatchingRegExp(int $length): string 92 | { 93 | switch ($length) { 94 | case 1: 95 | $regExp = '\d{1,2}'; 96 | break; 97 | case 3: 98 | $regExp = implode('|', self::$shortMonths); 99 | break; 100 | case 4: 101 | $regExp = implode('|', self::$months); 102 | break; 103 | case 5: 104 | $regExp = '[JFMASOND]'; 105 | break; 106 | default: 107 | $regExp = '\d{1,'.$length.'}'; 108 | break; 109 | } 110 | 111 | return $regExp; 112 | } 113 | 114 | /** 115 | * {@inheritdoc} 116 | */ 117 | public function extractDateOptions(string $matched, int $length): array 118 | { 119 | if (!is_numeric($matched)) { 120 | if (3 === $length) { 121 | $matched = self::$flippedShortMonths[$matched] + 1; 122 | } elseif (4 === $length) { 123 | $matched = self::$flippedMonths[$matched] + 1; 124 | } elseif (5 === $length) { 125 | // IntlDateFormatter::parse() always returns false for MMMMM or LLLLL 126 | $matched = false; 127 | } 128 | } else { 129 | $matched = (int) $matched; 130 | } 131 | 132 | return [ 133 | 'month' => $matched, 134 | ]; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/AbstractDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Filesystem\Filesystem; 15 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 16 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReader; 17 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 18 | use Symfony\Component\Intl\Data\Bundle\Reader\IntlBundleReader; 19 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 20 | 21 | /** 22 | * The rule for compiling the currency bundle. 23 | * 24 | * @author Bernhard Schussek 25 | * 26 | * @internal 27 | */ 28 | abstract class AbstractDataGenerator 29 | { 30 | private $compiler; 31 | private $dirName; 32 | 33 | public function __construct(BundleCompilerInterface $compiler, string $dirName) 34 | { 35 | $this->compiler = $compiler; 36 | $this->dirName = $dirName; 37 | } 38 | 39 | public function generateData(GeneratorConfig $config) 40 | { 41 | $filesystem = new Filesystem(); 42 | $localeScanner = new LocaleScanner(); 43 | $reader = new BundleEntryReader(new IntlBundleReader()); 44 | 45 | $writers = $config->getBundleWriters(); 46 | $tempDir = sys_get_temp_dir().'/icu-data-'.$this->dirName; 47 | 48 | // Prepare filesystem directories 49 | foreach ($writers as $targetDir => $writer) { 50 | $filesystem->remove($targetDir.'/'.$this->dirName); 51 | $filesystem->mkdir($targetDir.'/'.$this->dirName); 52 | } 53 | 54 | $filesystem->remove($tempDir); 55 | $filesystem->mkdir($tempDir); 56 | 57 | $locales = $this->scanLocales($localeScanner, $config->getSourceDir()); 58 | 59 | $this->compileTemporaryBundles($this->compiler, $config->getSourceDir(), $tempDir); 60 | 61 | $this->preGenerate(); 62 | 63 | foreach ($locales as $locale) { 64 | $localeData = $this->generateDataForLocale($reader, $tempDir, $locale); 65 | 66 | if (null !== $localeData) { 67 | foreach ($writers as $targetDir => $writer) { 68 | $writer->write($targetDir.'/'.$this->dirName, $locale, $localeData); 69 | } 70 | } 71 | } 72 | 73 | $rootData = $this->generateDataForRoot($reader, $tempDir); 74 | 75 | if (null !== $rootData) { 76 | foreach ($writers as $targetDir => $writer) { 77 | $writer->write($targetDir.'/'.$this->dirName, 'root', $rootData); 78 | } 79 | } 80 | 81 | $metaData = $this->generateDataForMeta($reader, $tempDir); 82 | 83 | if (null !== $metaData) { 84 | foreach ($writers as $targetDir => $writer) { 85 | $writer->write($targetDir.'/'.$this->dirName, 'meta', $metaData); 86 | } 87 | } 88 | 89 | // Clean up 90 | $filesystem->remove($tempDir); 91 | } 92 | 93 | /** 94 | * @return string[] 95 | */ 96 | abstract protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array; 97 | 98 | abstract protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir); 99 | 100 | abstract protected function preGenerate(); 101 | 102 | abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array; 103 | 104 | abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array; 105 | 106 | abstract protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array; 107 | } 108 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Util/IntlTestHelper.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Util; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Symfony\Component\Intl\Intl; 16 | 17 | /** 18 | * Helper class for preparing test cases that rely on the Intl component. 19 | * 20 | * Any test that tests functionality relying on either the intl classes or 21 | * the resource bundle data should call either of the methods 22 | * {@link requireIntl()} or {@link requireFullIntl()}. Calling 23 | * {@link requireFullIntl()} is only necessary if you use functionality in the 24 | * test that is not provided by the stub intl implementation. 25 | * 26 | * @author Bernhard Schussek 27 | */ 28 | class IntlTestHelper 29 | { 30 | /** 31 | * Should be called before tests that work fine with the stub implementation. 32 | */ 33 | public static function requireIntl(TestCase $testCase, $minimumIcuVersion = null) 34 | { 35 | if (null === $minimumIcuVersion) { 36 | $minimumIcuVersion = Intl::getIcuStubVersion(); 37 | } 38 | 39 | // We only run tests if the version is *one specific version*. 40 | // This condition is satisfied if 41 | // 42 | // * the intl extension is loaded with version Intl::getIcuStubVersion() 43 | // * the intl extension is not loaded 44 | 45 | if ($minimumIcuVersion && IcuVersion::compare(Intl::getIcuVersion(), $minimumIcuVersion, '<', 1)) { 46 | $testCase->markTestSkipped('ICU version '.$minimumIcuVersion.' is required.'); 47 | } 48 | 49 | // Normalize the default locale in case this is not done explicitly 50 | // in the test 51 | \Locale::setDefault('en'); 52 | 53 | // Consequently, tests will 54 | // 55 | // * run only for one ICU version (see Intl::getIcuStubVersion()) 56 | // there is no need to add control structures to your tests that 57 | // change the test depending on the ICU version. 58 | // 59 | // Tests should only rely on functionality that is implemented in the 60 | // stub classes. 61 | } 62 | 63 | /** 64 | * Should be called before tests that require a feature-complete intl 65 | * implementation. 66 | */ 67 | public static function requireFullIntl(TestCase $testCase, $minimumIcuVersion = null) 68 | { 69 | // We only run tests if the intl extension is loaded... 70 | if (!Intl::isExtensionLoaded()) { 71 | $testCase->markTestSkipped('Extension intl is required.'); 72 | } 73 | 74 | self::requireIntl($testCase, $minimumIcuVersion); 75 | 76 | // Consequently, tests will 77 | // 78 | // * run only for one ICU version (see Intl::getIcuStubVersion()) 79 | // there is no need to add control structures to your tests that 80 | // change the test depending on the ICU version. 81 | // * always use the C intl classes 82 | } 83 | 84 | /** 85 | * Skips the test unless the current system has a 32bit architecture. 86 | */ 87 | public static function require32Bit(TestCase $testCase) 88 | { 89 | if (4 !== PHP_INT_SIZE) { 90 | $testCase->markTestSkipped('PHP 32 bit is required.'); 91 | } 92 | } 93 | 94 | /** 95 | * Skips the test unless the current system has a 64bit architecture. 96 | */ 97 | public static function require64Bit(TestCase $testCase) 98 | { 99 | if (8 !== PHP_INT_SIZE) { 100 | $testCase->markTestSkipped('PHP 64 bit is required.'); 101 | } 102 | } 103 | 104 | /** 105 | * Must not be instantiated. 106 | */ 107 | private function __construct() 108 | { 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Timezones.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | use Symfony\Component\Intl\Exception\RuntimeException; 16 | 17 | /** 18 | * Gives access to timezone-related ICU data. 19 | * 20 | * @author Roland Franssen 21 | */ 22 | final class Timezones extends ResourceBundle 23 | { 24 | /** 25 | * @return string[] 26 | */ 27 | public static function getIds(): array 28 | { 29 | return self::readEntry(['Zones'], 'meta'); 30 | } 31 | 32 | public static function exists(string $timezone): bool 33 | { 34 | try { 35 | self::readEntry(['Names', $timezone]); 36 | 37 | return true; 38 | } catch (MissingResourceException $e) { 39 | try { 40 | new \DateTimeZone($timezone); 41 | 42 | return true; 43 | } catch (\Exception $e) { 44 | return false; 45 | } 46 | } 47 | } 48 | 49 | /** 50 | * @throws MissingResourceException if the timezone identifier does not exist or is an alias 51 | */ 52 | public static function getName(string $timezone, string $displayLocale = null): string 53 | { 54 | return self::readEntry(['Names', $timezone], $displayLocale); 55 | } 56 | 57 | /** 58 | * @return string[] 59 | */ 60 | public static function getNames(string $displayLocale = null): array 61 | { 62 | return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale); 63 | } 64 | 65 | /** 66 | * @throws \Exception if the timezone identifier does not exist 67 | * @throws RuntimeException if there's no timezone DST transition information available 68 | */ 69 | public static function getRawOffset(string $timezone, int $timestamp = null): int 70 | { 71 | if (null === $timestamp) { 72 | $timestamp = time(); 73 | } 74 | 75 | $transitions = (new \DateTimeZone($timezone))->getTransitions($timestamp, $timestamp); 76 | 77 | if (!isset($transitions[0]['offset'])) { 78 | throw new RuntimeException('No timezone transitions available.'); 79 | } 80 | 81 | return $transitions[0]['offset']; 82 | } 83 | 84 | public static function getGmtOffset(string $timezone, int $timestamp = null, string $displayLocale = null): string 85 | { 86 | $offset = self::getRawOffset($timezone, $timestamp); 87 | $abs = abs($offset); 88 | 89 | return sprintf(self::readEntry(['Meta', 'GmtFormat'], $displayLocale), sprintf(self::readEntry(['Meta', 'HourFormat'.(0 <= $offset ? 'Pos' : 'Neg')], $displayLocale), $abs / 3600, $abs / 60 % 60)); 90 | } 91 | 92 | /** 93 | * @throws MissingResourceException if the timezone identifier has no associated country code 94 | */ 95 | public static function getCountryCode(string $timezone): string 96 | { 97 | return self::readEntry(['ZoneToCountry', $timezone], 'meta'); 98 | } 99 | 100 | /** 101 | * @throws MissingResourceException if the country code does not exist 102 | */ 103 | public static function forCountryCode(string $country): array 104 | { 105 | try { 106 | return self::readEntry(['CountryToZone', $country], 'meta'); 107 | } catch (MissingResourceException $e) { 108 | if (Countries::exists($country)) { 109 | return []; 110 | } 111 | 112 | if (Countries::exists(strtoupper($country))) { 113 | throw new MissingResourceException(sprintf('Country codes must be in uppercase, but "%s" was passed. Try with "%s" country code instead.', $country, strtoupper($country))); 114 | } 115 | 116 | throw $e; 117 | } 118 | } 119 | 120 | protected static function getPath(): string 121 | { 122 | return Intl::getDataDirectory().'/'.Intl::TIMEZONE_DIR; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Intl.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | /** 15 | * Gives access to internationalization data. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | final class Intl 20 | { 21 | /** 22 | * The number of resource bundles to buffer. Loading the same resource 23 | * bundle for n locales takes up n spots in the buffer. 24 | */ 25 | const BUFFER_SIZE = 10; 26 | 27 | /** 28 | * The directory name of the currency data. 29 | */ 30 | const CURRENCY_DIR = 'currencies'; 31 | 32 | /** 33 | * The directory name of the language data. 34 | */ 35 | const LANGUAGE_DIR = 'languages'; 36 | 37 | /** 38 | * The directory name of the script data. 39 | */ 40 | const SCRIPT_DIR = 'scripts'; 41 | 42 | /** 43 | * The directory name of the locale data. 44 | */ 45 | const LOCALE_DIR = 'locales'; 46 | 47 | /** 48 | * The directory name of the region data. 49 | */ 50 | const REGION_DIR = 'regions'; 51 | 52 | /** 53 | * The directory name of the zone data. 54 | */ 55 | public const TIMEZONE_DIR = 'timezones'; 56 | 57 | /** 58 | * @var string|bool|null 59 | */ 60 | private static $icuVersion = false; 61 | 62 | /** 63 | * @var string 64 | */ 65 | private static $icuDataVersion = false; 66 | 67 | /** 68 | * Returns whether the intl extension is installed. 69 | * 70 | * @return bool Returns true if the intl extension is installed, false otherwise 71 | */ 72 | public static function isExtensionLoaded(): bool 73 | { 74 | return class_exists('\ResourceBundle'); 75 | } 76 | 77 | /** 78 | * Returns the version of the installed ICU library. 79 | * 80 | * @return string|null The ICU version or NULL if it could not be determined 81 | */ 82 | public static function getIcuVersion(): ?string 83 | { 84 | if (false === self::$icuVersion) { 85 | if (!self::isExtensionLoaded()) { 86 | self::$icuVersion = self::getIcuStubVersion(); 87 | } elseif (\defined('INTL_ICU_VERSION')) { 88 | self::$icuVersion = INTL_ICU_VERSION; 89 | } else { 90 | try { 91 | $reflector = new \ReflectionExtension('intl'); 92 | ob_start(); 93 | $reflector->info(); 94 | $output = strip_tags(ob_get_clean()); 95 | preg_match('/^ICU version (?:=>)?(.*)$/m', $output, $matches); 96 | 97 | self::$icuVersion = trim($matches[1]); 98 | } catch (\ReflectionException $e) { 99 | self::$icuVersion = null; 100 | } 101 | } 102 | } 103 | 104 | return self::$icuVersion; 105 | } 106 | 107 | /** 108 | * Returns the version of the installed ICU data. 109 | * 110 | * @return string The version of the installed ICU data 111 | */ 112 | public static function getIcuDataVersion(): string 113 | { 114 | if (false === self::$icuDataVersion) { 115 | self::$icuDataVersion = trim(file_get_contents(self::getDataDirectory().'/version.txt')); 116 | } 117 | 118 | return self::$icuDataVersion; 119 | } 120 | 121 | /** 122 | * Returns the ICU version that the stub classes mimic. 123 | * 124 | * @return string The ICU version of the stub classes 125 | */ 126 | public static function getIcuStubVersion(): string 127 | { 128 | return '67.1'; 129 | } 130 | 131 | /** 132 | * Returns the absolute path to the data directory. 133 | * 134 | * @return string The absolute path to the data directory 135 | */ 136 | public static function getDataDirectory(): string 137 | { 138 | return __DIR__.'/Resources/data'; 139 | } 140 | 141 | /** 142 | * This class must not be instantiated. 143 | */ 144 | private function __construct() 145 | { 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Currencies.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Gives access to currency-related ICU data. 18 | * 19 | * @author Bernhard Schussek 20 | * @author Roland Franssen 21 | */ 22 | final class Currencies extends ResourceBundle 23 | { 24 | private const INDEX_SYMBOL = 0; 25 | private const INDEX_NAME = 1; 26 | private const INDEX_FRACTION_DIGITS = 0; 27 | private const INDEX_ROUNDING_INCREMENT = 1; 28 | 29 | /** 30 | * @return string[] 31 | */ 32 | public static function getCurrencyCodes(): array 33 | { 34 | return self::readEntry(['Currencies'], 'meta'); 35 | } 36 | 37 | public static function exists(string $currency): bool 38 | { 39 | try { 40 | self::readEntry(['Names', $currency, self::INDEX_NAME]); 41 | 42 | return true; 43 | } catch (MissingResourceException $e) { 44 | return false; 45 | } 46 | } 47 | 48 | /** 49 | * @throws MissingResourceException if the currency code does not exist 50 | */ 51 | public static function getName(string $currency, string $displayLocale = null): string 52 | { 53 | return self::readEntry(['Names', $currency, self::INDEX_NAME], $displayLocale); 54 | } 55 | 56 | /** 57 | * @return string[] 58 | */ 59 | public static function getNames(string $displayLocale = null): array 60 | { 61 | // ==================================================================== 62 | // For reference: It is NOT possible to return names indexed by 63 | // numeric code here, because some numeric codes map to multiple 64 | // 3-letter codes (e.g. 32 => "ARA", "ARP", "ARS") 65 | // ==================================================================== 66 | 67 | $names = self::readEntry(['Names'], $displayLocale); 68 | 69 | if ($names instanceof \Traversable) { 70 | $names = iterator_to_array($names); 71 | } 72 | 73 | array_walk($names, function (&$value) { 74 | $value = $value[self::INDEX_NAME]; 75 | }); 76 | 77 | return self::asort($names, $displayLocale); 78 | } 79 | 80 | /** 81 | * @throws MissingResourceException if the currency code does not exist 82 | */ 83 | public static function getSymbol(string $currency, string $displayLocale = null): string 84 | { 85 | return self::readEntry(['Names', $currency, self::INDEX_SYMBOL], $displayLocale); 86 | } 87 | 88 | public static function getFractionDigits(string $currency): int 89 | { 90 | try { 91 | return self::readEntry(['Meta', $currency, self::INDEX_FRACTION_DIGITS], 'meta'); 92 | } catch (MissingResourceException $e) { 93 | return self::readEntry(['Meta', 'DEFAULT', self::INDEX_FRACTION_DIGITS], 'meta'); 94 | } 95 | } 96 | 97 | /** 98 | * @return float|int 99 | */ 100 | public static function getRoundingIncrement(string $currency) 101 | { 102 | try { 103 | return self::readEntry(['Meta', $currency, self::INDEX_ROUNDING_INCREMENT], 'meta'); 104 | } catch (MissingResourceException $e) { 105 | return self::readEntry(['Meta', 'DEFAULT', self::INDEX_ROUNDING_INCREMENT], 'meta'); 106 | } 107 | } 108 | 109 | /** 110 | * @throws MissingResourceException if the currency code has no numeric code 111 | */ 112 | public static function getNumericCode(string $currency): int 113 | { 114 | return self::readEntry(['Alpha3ToNumeric', $currency], 'meta'); 115 | } 116 | 117 | /** 118 | * @throws MissingResourceException if the numeric code does not exist 119 | */ 120 | public static function forNumericCode(int $numericCode): array 121 | { 122 | return self::readEntry(['NumericToAlpha3', (string) $numericCode], 'meta'); 123 | } 124 | 125 | protected static function getPath(): string 126 | { 127 | return Intl::getDataDirectory().'/'.Intl::CURRENCY_DIR; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /vendor/symfony/intl/DateFormatter/DateFormat/TimezoneTransformer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 | 14 | use Symfony\Component\Intl\Exception\NotImplementedException; 15 | 16 | /** 17 | * Parser and formatter for time zone format. 18 | * 19 | * @author Igor Wiedler 20 | * 21 | * @internal 22 | */ 23 | class TimezoneTransformer extends Transformer 24 | { 25 | /** 26 | * {@inheritdoc} 27 | * 28 | * @throws NotImplementedException When time zone is different than UTC or GMT (Etc/GMT) 29 | */ 30 | public function format(\DateTime $dateTime, int $length): string 31 | { 32 | $timeZone = substr($dateTime->getTimezone()->getName(), 0, 3); 33 | 34 | if (!\in_array($timeZone, ['Etc', 'UTC', 'GMT'])) { 35 | throw new NotImplementedException('Time zone different than GMT or UTC is not supported as a formatting output.'); 36 | } 37 | 38 | if ('Etc' === $timeZone) { 39 | // i.e. Etc/GMT+1, Etc/UTC, Etc/Zulu 40 | $timeZone = substr($dateTime->getTimezone()->getName(), 4); 41 | } 42 | 43 | // From ICU >= 59.1 GMT and UTC are no longer unified 44 | if (\in_array($timeZone, ['UTC', 'UCT', 'Universal', 'Zulu'])) { 45 | // offset is not supported with UTC 46 | return $length > 3 ? 'Coordinated Universal Time' : 'UTC'; 47 | } 48 | 49 | $offset = (int) $dateTime->format('O'); 50 | 51 | // From ICU >= 4.8, the zero offset is no more used, example: GMT instead of GMT+00:00 52 | if (0 === $offset) { 53 | return $length > 3 ? 'Greenwich Mean Time' : 'GMT'; 54 | } 55 | 56 | if ($length > 3) { 57 | return $dateTime->format('\G\M\TP'); 58 | } 59 | 60 | return sprintf('GMT%s%d', ($offset >= 0 ? '+' : ''), $offset / 100); 61 | } 62 | 63 | /** 64 | * {@inheritdoc} 65 | */ 66 | public function getReverseMatchingRegExp(int $length): string 67 | { 68 | return 'GMT[+-]\d{2}:?\d{2}'; 69 | } 70 | 71 | /** 72 | * {@inheritdoc} 73 | */ 74 | public function extractDateOptions(string $matched, int $length): array 75 | { 76 | return [ 77 | 'timezone' => self::getEtcTimeZoneId($matched), 78 | ]; 79 | } 80 | 81 | /** 82 | * Get an Etc/GMT timezone identifier for the specified timezone. 83 | * 84 | * The PHP documentation for timezones states to not use the 'Other' time zones because them exists 85 | * "for backwards compatibility". However all Etc/GMT time zones are in the tz database 'etcetera' file, 86 | * which indicates they are not deprecated (neither are old names). 87 | * 88 | * Only GMT, Etc/Universal, Etc/Zulu, Etc/Greenwich, Etc/GMT-0, Etc/GMT+0 and Etc/GMT0 are old names and 89 | * are linked to Etc/GMT or Etc/UTC. 90 | * 91 | * @param string $formattedTimeZone A GMT timezone string (GMT-03:00, e.g.) 92 | * 93 | * @return string A timezone identifier 94 | * 95 | * @see https://php.net/timezones.others 96 | * 97 | * @throws NotImplementedException When the GMT time zone have minutes offset different than zero 98 | * @throws \InvalidArgumentException When the value can not be matched with pattern 99 | */ 100 | public static function getEtcTimeZoneId(string $formattedTimeZone): string 101 | { 102 | if (preg_match('/GMT(?P[+-])(?P\d{2}):?(?P\d{2})/', $formattedTimeZone, $matches)) { 103 | $hours = (int) $matches['hours']; 104 | $minutes = (int) $matches['minutes']; 105 | $signal = '-' === $matches['signal'] ? '+' : '-'; 106 | 107 | if (0 < $minutes) { 108 | throw new NotImplementedException(sprintf('It is not possible to use a GMT time zone with minutes offset different than zero (0). GMT time zone tried: "%s".', $formattedTimeZone)); 109 | } 110 | 111 | return 'Etc/GMT'.(0 !== $hours ? $signal.$hours : ''); 112 | } 113 | 114 | throw new \InvalidArgumentException(sprintf('The GMT time zone "%s" does not match with the supported formats GMT[+-]HH:MM or GMT[+-]HHMM.', $formattedTimeZone)); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Countries.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Gives access to region-related ICU data. 18 | * 19 | * @author Bernhard Schussek 20 | * @author Roland Franssen 21 | */ 22 | final class Countries extends ResourceBundle 23 | { 24 | /** 25 | * Returns all available countries. 26 | * 27 | * Countries are returned as uppercase ISO 3166 two-letter country codes. 28 | * 29 | * A full table of ISO 3166 country codes can be found here: 30 | * https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes 31 | * 32 | * This list only contains "officially assigned ISO 3166-1 alpha-2" country codes. 33 | * 34 | * @return string[] an array of canonical ISO 3166 alpha-2 country codes 35 | */ 36 | public static function getCountryCodes(): array 37 | { 38 | return self::readEntry(['Regions'], 'meta'); 39 | } 40 | 41 | /** 42 | * Returns all available countries (3 letters). 43 | * 44 | * Countries are returned as uppercase ISO 3166 three-letter country codes. 45 | * 46 | * This list only contains "officially assigned ISO 3166-1 alpha-3" country codes. 47 | * 48 | * @return string[] an array of canonical ISO 3166 alpha-3 country codes 49 | */ 50 | public static function getAlpha3Codes(): array 51 | { 52 | return self::readEntry(['Alpha2ToAlpha3'], 'meta'); 53 | } 54 | 55 | public static function getAlpha3Code(string $alpha2Code): string 56 | { 57 | return self::readEntry(['Alpha2ToAlpha3', $alpha2Code], 'meta'); 58 | } 59 | 60 | public static function getAlpha2Code(string $alpha3Code): string 61 | { 62 | return self::readEntry(['Alpha3ToAlpha2', $alpha3Code], 'meta'); 63 | } 64 | 65 | public static function exists(string $alpha2Code): bool 66 | { 67 | try { 68 | self::readEntry(['Names', $alpha2Code]); 69 | 70 | return true; 71 | } catch (MissingResourceException $e) { 72 | return false; 73 | } 74 | } 75 | 76 | public static function alpha3CodeExists(string $alpha3Code): bool 77 | { 78 | try { 79 | self::getAlpha2Code($alpha3Code); 80 | 81 | return true; 82 | } catch (MissingResourceException $e) { 83 | return false; 84 | } 85 | } 86 | 87 | /** 88 | * Gets the country name from its alpha2 code. 89 | * 90 | * @throws MissingResourceException if the country code does not exist 91 | */ 92 | public static function getName(string $country, string $displayLocale = null): string 93 | { 94 | return self::readEntry(['Names', $country], $displayLocale); 95 | } 96 | 97 | /** 98 | * Gets the country name from its alpha3 code. 99 | * 100 | * @throws MissingResourceException if the country code does not exist 101 | */ 102 | public static function getAlpha3Name(string $alpha3Code, string $displayLocale = null): string 103 | { 104 | return self::getName(self::getAlpha2Code($alpha3Code), $displayLocale); 105 | } 106 | 107 | /** 108 | * Gets the list of country names indexed with alpha2 codes as keys. 109 | * 110 | * @return string[] 111 | */ 112 | public static function getNames($displayLocale = null): array 113 | { 114 | return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale); 115 | } 116 | 117 | /** 118 | * Gets the list of country names indexed with alpha3 codes as keys. 119 | * 120 | * Same as method getNames, but with alpha3 codes instead of alpha2 codes as keys. 121 | * 122 | * @return string[] 123 | */ 124 | public static function getAlpha3Names($displayLocale = null): array 125 | { 126 | $alpha2Names = self::getNames($displayLocale); 127 | $alpha3Names = []; 128 | foreach ($alpha2Names as $alpha2Code => $name) { 129 | $alpha3Names[self::getAlpha3Code($alpha2Code)] = $name; 130 | } 131 | 132 | return $alpha3Names; 133 | } 134 | 135 | protected static function getPath(): string 136 | { 137 | return Intl::getDataDirectory().'/'.Intl::REGION_DIR; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/CurrencyDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 15 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 16 | use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle; 17 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 18 | 19 | /** 20 | * The rule for compiling the currency bundle. 21 | * 22 | * @author Bernhard Schussek 23 | * 24 | * @internal 25 | */ 26 | class CurrencyDataGenerator extends AbstractDataGenerator 27 | { 28 | private static $blacklist = [ 29 | 'XBA' => true, // European Composite Unit 30 | 'XBB' => true, // European Monetary Unit 31 | 'XBC' => true, // European Unit of Account (XBC) 32 | 'XBD' => true, // European Unit of Account (XBD) 33 | 'XUA' => true, // ADB Unit of Account 34 | 'XAU' => true, // Gold 35 | 'XAG' => true, // Silver 36 | 'XPT' => true, // Platinum 37 | 'XPD' => true, // Palladium 38 | 'XSU' => true, // Sucre 39 | 'XDR' => true, // Special Drawing Rights 40 | 'XTS' => true, // Testing Currency Code 41 | 'XXX' => true, // Unknown Currency 42 | ]; 43 | 44 | /** 45 | * Collects all available currency codes. 46 | * 47 | * @var string[] 48 | */ 49 | private $currencyCodes = []; 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array 55 | { 56 | return $scanner->scanLocales($sourceDir.'/curr'); 57 | } 58 | 59 | /** 60 | * {@inheritdoc} 61 | */ 62 | protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir) 63 | { 64 | $compiler->compile($sourceDir.'/curr', $tempDir); 65 | $compiler->compile($sourceDir.'/misc/currencyNumericCodes.txt', $tempDir); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | protected function preGenerate() 72 | { 73 | $this->currencyCodes = []; 74 | } 75 | 76 | /** 77 | * {@inheritdoc} 78 | */ 79 | protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array 80 | { 81 | $localeBundle = $reader->read($tempDir, $displayLocale); 82 | 83 | if (isset($localeBundle['Currencies']) && null !== $localeBundle['Currencies']) { 84 | $data = [ 85 | 'Names' => $this->generateSymbolNamePairs($localeBundle), 86 | ]; 87 | 88 | $this->currencyCodes = array_merge($this->currencyCodes, array_keys($data['Names'])); 89 | 90 | return $data; 91 | } 92 | 93 | return null; 94 | } 95 | 96 | /** 97 | * {@inheritdoc} 98 | */ 99 | protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array 100 | { 101 | $rootBundle = $reader->read($tempDir, 'root'); 102 | 103 | return [ 104 | 'Names' => $this->generateSymbolNamePairs($rootBundle), 105 | ]; 106 | } 107 | 108 | /** 109 | * {@inheritdoc} 110 | */ 111 | protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array 112 | { 113 | $supplementalDataBundle = $reader->read($tempDir, 'supplementalData'); 114 | $numericCodesBundle = $reader->read($tempDir, 'currencyNumericCodes'); 115 | 116 | $this->currencyCodes = array_unique($this->currencyCodes); 117 | 118 | sort($this->currencyCodes); 119 | 120 | $data = [ 121 | 'Currencies' => $this->currencyCodes, 122 | 'Meta' => $this->generateCurrencyMeta($supplementalDataBundle), 123 | 'Alpha3ToNumeric' => $this->generateAlpha3ToNumericMapping($numericCodesBundle, $this->currencyCodes), 124 | ]; 125 | 126 | $data['NumericToAlpha3'] = $this->generateNumericToAlpha3Mapping($data['Alpha3ToNumeric']); 127 | 128 | return $data; 129 | } 130 | 131 | private function generateSymbolNamePairs(ArrayAccessibleResourceBundle $rootBundle): array 132 | { 133 | $symbolNamePairs = iterator_to_array($rootBundle['Currencies']); 134 | 135 | // Remove unwanted currencies 136 | $symbolNamePairs = array_diff_key($symbolNamePairs, self::$blacklist); 137 | 138 | return $symbolNamePairs; 139 | } 140 | 141 | private function generateCurrencyMeta(ArrayAccessibleResourceBundle $supplementalDataBundle): array 142 | { 143 | // The metadata is already de-duplicated. It contains one key "DEFAULT" 144 | // which is used for currencies that don't have dedicated entries. 145 | return iterator_to_array($supplementalDataBundle['CurrencyMeta']); 146 | } 147 | 148 | private function generateAlpha3ToNumericMapping(ArrayAccessibleResourceBundle $numericCodesBundle, array $currencyCodes): array 149 | { 150 | $alpha3ToNumericMapping = iterator_to_array($numericCodesBundle['codeMap']); 151 | 152 | asort($alpha3ToNumericMapping); 153 | 154 | // Filter unknown currencies (e.g. "AYM") 155 | $alpha3ToNumericMapping = array_intersect_key($alpha3ToNumericMapping, array_flip($currencyCodes)); 156 | 157 | return $alpha3ToNumericMapping; 158 | } 159 | 160 | private function generateNumericToAlpha3Mapping(array $alpha3ToNumericMapping): array 161 | { 162 | $numericToAlpha3Mapping = []; 163 | 164 | foreach ($alpha3ToNumericMapping as $alpha3 => $numeric) { 165 | // Make sure that the mapping is stored as table and not as array 166 | $numeric = (string) $numeric; 167 | 168 | if (!isset($numericToAlpha3Mapping[$numeric])) { 169 | $numericToAlpha3Mapping[$numeric] = []; 170 | } 171 | 172 | $numericToAlpha3Mapping[$numeric][] = $alpha3; 173 | } 174 | 175 | return $numericToAlpha3Mapping; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Languages.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | use Symfony\Component\Intl\Exception\MissingResourceException; 15 | 16 | /** 17 | * Gives access to language-related ICU data. 18 | * 19 | * @author Bernhard Schussek 20 | * @author Roland Franssen 21 | */ 22 | final class Languages extends ResourceBundle 23 | { 24 | /** 25 | * Returns all available languages as two-letter codes. 26 | * 27 | * Languages are returned as lowercase ISO 639-1 two-letter language codes. 28 | * For languages that don't have a two-letter code, the ISO 639-2 29 | * three-letter code is used instead. 30 | * 31 | * A full table of ISO 639 language codes can be found here: 32 | * http://www-01.sil.org/iso639-3/codes.asp 33 | * 34 | * @return string[] an array of canonical ISO 639-1 language codes 35 | */ 36 | public static function getLanguageCodes(): array 37 | { 38 | return self::readEntry(['Languages'], 'meta'); 39 | } 40 | 41 | public static function exists(string $language): bool 42 | { 43 | try { 44 | self::readEntry(['Names', $language]); 45 | 46 | return true; 47 | } catch (MissingResourceException $e) { 48 | return false; 49 | } 50 | } 51 | 52 | /** 53 | * Gets the language name from its alpha2 code. 54 | * 55 | * A full locale may be passed to obtain a more localized language name, e.g. "American English" for "en_US". 56 | * 57 | * @throws MissingResourceException if the language code does not exist 58 | */ 59 | public static function getName(string $language, string $displayLocale = null): string 60 | { 61 | try { 62 | return self::readEntry(['Names', $language], $displayLocale); 63 | } catch (MissingResourceException $e) { 64 | try { 65 | return self::readEntry(['LocalizedNames', $language], $displayLocale); 66 | } catch (MissingResourceException $e) { 67 | if (false !== $i = strrpos($language, '_')) { 68 | return self::getName(substr($language, 0, $i), $displayLocale); 69 | } 70 | 71 | throw $e; 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * Gets the list of language names indexed with alpha2 codes as keys. 78 | * 79 | * @return string[] 80 | */ 81 | public static function getNames(string $displayLocale = null): array 82 | { 83 | return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale); 84 | } 85 | 86 | /** 87 | * Returns the ISO 639-2 three-letter code of a language, given a two-letter code. 88 | * 89 | * @throws MissingResourceException if the language has no corresponding three-letter code 90 | */ 91 | public static function getAlpha3Code(string $language): string 92 | { 93 | return self::readEntry(['Alpha2ToAlpha3', $language], 'meta'); 94 | } 95 | 96 | /** 97 | * Returns the ISO 639-1 two-letter code of a language, given a three letter code. 98 | * 99 | * @throws MissingResourceException if the language has no corresponding three-letter code 100 | */ 101 | public static function getAlpha2Code(string $language): string 102 | { 103 | return self::readEntry(['Alpha3ToAlpha2', $language], 'meta'); 104 | } 105 | 106 | /** 107 | * Returns all available languages as three-letter codes. 108 | * 109 | * Languages are returned as lowercase ISO 639-2 three-letter language codes. 110 | * 111 | * @return string[] an array of canonical ISO 639-2 language codes 112 | */ 113 | public static function getAlpha3Codes(): array 114 | { 115 | return self::readEntry(['Alpha3Languages'], 'meta'); 116 | } 117 | 118 | /** 119 | * @param string $language ISO 639-2 three-letter language code 120 | */ 121 | public static function alpha3CodeExists(string $language): bool 122 | { 123 | try { 124 | self::getAlpha2Code($language); 125 | 126 | return true; 127 | } catch (MissingResourceException $e) { 128 | static $cache; 129 | if (null === $cache) { 130 | $cache = array_flip(self::getAlpha3Codes()); 131 | } 132 | 133 | return isset($cache[$language]); 134 | } 135 | } 136 | 137 | /** 138 | * Gets the language name from its ISO 639-2 three-letter code. 139 | * 140 | * @throws MissingResourceException if the country code does not exists 141 | */ 142 | public static function getAlpha3Name(string $language, string $displayLocale = null): string 143 | { 144 | try { 145 | return self::getName(self::getAlpha2Code($language), $displayLocale); 146 | } catch (MissingResourceException $e) { 147 | if (3 === \strlen($language)) { 148 | return self::getName($language, $displayLocale); 149 | } 150 | 151 | throw $e; 152 | } 153 | } 154 | 155 | /** 156 | * Gets the list of language names indexed with ISO 639-2 three-letter codes as keys. 157 | * 158 | * Same as method getNames, but with ISO 639-2 three-letter codes instead of ISO 639-1 codes as keys. 159 | * 160 | * @return string[] 161 | */ 162 | public static function getAlpha3Names($displayLocale = null): array 163 | { 164 | $alpha2Names = self::getNames($displayLocale); 165 | $alpha3Names = []; 166 | foreach ($alpha2Names as $alpha2Code => $name) { 167 | if (3 === \strlen($alpha2Code)) { 168 | $alpha3Names[$alpha2Code] = $name; 169 | continue; 170 | } 171 | try { 172 | $alpha3Names[self::getAlpha3Code($alpha2Code)] = $name; 173 | } catch (MissingResourceException $e) { 174 | } 175 | } 176 | 177 | return $alpha3Names; 178 | } 179 | 180 | protected static function getPath(): string 181 | { 182 | return Intl::getDataDirectory().'/'.Intl::LANGUAGE_DIR; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Writer/TextBundleWriter.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Writer; 13 | 14 | /** 15 | * Writes .txt resource bundles. 16 | * 17 | * The resulting files can be converted to binary .res files using a 18 | * {@link \Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface} 19 | * implementation. 20 | * 21 | * @author Bernhard Schussek 22 | * 23 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 24 | * 25 | * @internal 26 | */ 27 | class TextBundleWriter implements BundleWriterInterface 28 | { 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function write(string $path, string $locale, $data, bool $fallback = true) 33 | { 34 | $file = fopen($path.'/'.$locale.'.txt', 'w'); 35 | 36 | $this->writeResourceBundle($file, $locale, $data, $fallback); 37 | 38 | fclose($file); 39 | } 40 | 41 | /** 42 | * Writes a "resourceBundle" node. 43 | * 44 | * @param resource $file The file handle to write to 45 | * @param mixed $value The value of the node 46 | * 47 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 48 | */ 49 | private function writeResourceBundle($file, string $bundleName, $value, bool $fallback) 50 | { 51 | fwrite($file, $bundleName); 52 | 53 | $this->writeTable($file, $value, 0, $fallback); 54 | 55 | fwrite($file, "\n"); 56 | } 57 | 58 | /** 59 | * Writes a "resource" node. 60 | * 61 | * @param resource $file The file handle to write to 62 | * @param mixed $value The value of the node 63 | * 64 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 65 | */ 66 | private function writeResource($file, $value, int $indentation, bool $requireBraces = true) 67 | { 68 | if (\is_int($value)) { 69 | $this->writeInteger($file, $value); 70 | 71 | return; 72 | } 73 | 74 | if ($value instanceof \Traversable) { 75 | $value = iterator_to_array($value); 76 | } 77 | 78 | if (\is_array($value)) { 79 | $intValues = \count($value) === \count(array_filter($value, 'is_int')); 80 | 81 | $keys = array_keys($value); 82 | 83 | // check that the keys are 0-indexed and ascending 84 | $intKeys = $keys === range(0, \count($keys) - 1); 85 | 86 | if ($intValues && $intKeys) { 87 | $this->writeIntVector($file, $value, $indentation); 88 | 89 | return; 90 | } 91 | 92 | if ($intKeys) { 93 | $this->writeArray($file, $value, $indentation); 94 | 95 | return; 96 | } 97 | 98 | $this->writeTable($file, $value, $indentation); 99 | 100 | return; 101 | } 102 | 103 | if (\is_bool($value)) { 104 | $value = $value ? 'true' : 'false'; 105 | } 106 | 107 | $this->writeString($file, (string) $value, $requireBraces); 108 | } 109 | 110 | /** 111 | * Writes an "integer" node. 112 | * 113 | * @param resource $file The file handle to write to 114 | * 115 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 116 | */ 117 | private function writeInteger($file, int $value) 118 | { 119 | fprintf($file, ':int{%d}', $value); 120 | } 121 | 122 | /** 123 | * Writes an "intvector" node. 124 | * 125 | * @param resource $file The file handle to write to 126 | * 127 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 128 | */ 129 | private function writeIntVector($file, array $value, int $indentation) 130 | { 131 | fwrite($file, ":intvector{\n"); 132 | 133 | foreach ($value as $int) { 134 | fprintf($file, "%s%d,\n", str_repeat(' ', $indentation + 1), $int); 135 | } 136 | 137 | fprintf($file, '%s}', str_repeat(' ', $indentation)); 138 | } 139 | 140 | /** 141 | * Writes a "string" node. 142 | * 143 | * @param resource $file The file handle to write to 144 | * 145 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 146 | */ 147 | private function writeString($file, string $value, bool $requireBraces = true) 148 | { 149 | if ($requireBraces) { 150 | fprintf($file, '{"%s"}', $value); 151 | 152 | return; 153 | } 154 | 155 | fprintf($file, '"%s"', $value); 156 | } 157 | 158 | /** 159 | * Writes an "array" node. 160 | * 161 | * @param resource $file The file handle to write to 162 | * 163 | * @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt 164 | */ 165 | private function writeArray($file, array $value, int $indentation) 166 | { 167 | fwrite($file, "{\n"); 168 | 169 | foreach ($value as $entry) { 170 | fwrite($file, str_repeat(' ', $indentation + 1)); 171 | 172 | $this->writeResource($file, $entry, $indentation + 1, false); 173 | 174 | fwrite($file, ",\n"); 175 | } 176 | 177 | fprintf($file, '%s}', str_repeat(' ', $indentation)); 178 | } 179 | 180 | /** 181 | * Writes a "table" node. 182 | * 183 | * @param resource $file The file handle to write to 184 | */ 185 | private function writeTable($file, iterable $value, int $indentation, bool $fallback = true) 186 | { 187 | if (!$fallback) { 188 | fwrite($file, ':table(nofallback)'); 189 | } 190 | 191 | fwrite($file, "{\n"); 192 | 193 | foreach ($value as $key => $entry) { 194 | fwrite($file, str_repeat(' ', $indentation + 1)); 195 | 196 | // escape colons, otherwise they are interpreted as resource types 197 | if (false !== strpos($key, ':') || false !== strpos($key, ' ')) { 198 | $key = '"'.$key.'"'; 199 | } 200 | 201 | fwrite($file, $key); 202 | 203 | $this->writeResource($file, $entry, $indentation + 1); 204 | 205 | fwrite($file, "\n"); 206 | } 207 | 208 | fprintf($file, '%s}', str_repeat(' ', $indentation)); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Bundle/Reader/BundleEntryReader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Bundle\Reader; 13 | 14 | use Symfony\Component\Intl\Data\Util\RecursiveArrayAccess; 15 | use Symfony\Component\Intl\Exception\MissingResourceException; 16 | use Symfony\Component\Intl\Exception\OutOfBoundsException; 17 | use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException; 18 | use Symfony\Component\Intl\Locale; 19 | 20 | /** 21 | * Default implementation of {@link BundleEntryReaderInterface}. 22 | * 23 | * @author Bernhard Schussek 24 | * 25 | * @see BundleEntryReaderInterface 26 | * 27 | * @internal 28 | */ 29 | class BundleEntryReader implements BundleEntryReaderInterface 30 | { 31 | private $reader; 32 | 33 | /** 34 | * A mapping of locale aliases to locales. 35 | */ 36 | private $localeAliases = []; 37 | 38 | /** 39 | * Creates an entry reader based on the given resource bundle reader. 40 | */ 41 | public function __construct(BundleReaderInterface $reader) 42 | { 43 | $this->reader = $reader; 44 | } 45 | 46 | /** 47 | * Stores a mapping of locale aliases to locales. 48 | * 49 | * This mapping is used when reading entries and merging them with their 50 | * fallback locales. If an entry is read for a locale alias (e.g. "mo") 51 | * that points to a locale with a fallback locale ("ro_MD"), the reader 52 | * can continue at the correct fallback locale ("ro"). 53 | * 54 | * @param array $localeAliases A mapping of locale aliases to locales 55 | */ 56 | public function setLocaleAliases(array $localeAliases) 57 | { 58 | $this->localeAliases = $localeAliases; 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | */ 64 | public function read(string $path, string $locale) 65 | { 66 | return $this->reader->read($path, $locale); 67 | } 68 | 69 | /** 70 | * {@inheritdoc} 71 | */ 72 | public function readEntry(string $path, string $locale, array $indices, bool $fallback = true) 73 | { 74 | $entry = null; 75 | $isMultiValued = false; 76 | $readSucceeded = false; 77 | $exception = null; 78 | $currentLocale = $locale; 79 | $testedLocales = []; 80 | 81 | while (null !== $currentLocale) { 82 | // Resolve any aliases to their target locales 83 | if (isset($this->localeAliases[$currentLocale])) { 84 | $currentLocale = $this->localeAliases[$currentLocale]; 85 | } 86 | 87 | try { 88 | $data = $this->reader->read($path, $currentLocale); 89 | $currentEntry = RecursiveArrayAccess::get($data, $indices); 90 | $readSucceeded = true; 91 | 92 | $isCurrentTraversable = $currentEntry instanceof \Traversable; 93 | $isCurrentMultiValued = $isCurrentTraversable || \is_array($currentEntry); 94 | 95 | // Return immediately if fallback is disabled or we are dealing 96 | // with a scalar non-null entry 97 | if (!$fallback || (!$isCurrentMultiValued && null !== $currentEntry)) { 98 | return $currentEntry; 99 | } 100 | 101 | // ========================================================= 102 | // Fallback is enabled, entry is either multi-valued or NULL 103 | // ========================================================= 104 | 105 | // If entry is multi-valued, convert to array 106 | if ($isCurrentTraversable) { 107 | $currentEntry = iterator_to_array($currentEntry); 108 | } 109 | 110 | // If previously read entry was multi-valued too, merge them 111 | if ($isCurrentMultiValued && $isMultiValued) { 112 | $currentEntry = array_merge($currentEntry, $entry); 113 | } 114 | 115 | // Keep the previous entry if the current entry is NULL 116 | if (null !== $currentEntry) { 117 | $entry = $currentEntry; 118 | } 119 | 120 | // If this or the previous entry was multi-valued, we are dealing 121 | // with a merged, multi-valued entry now 122 | $isMultiValued = $isMultiValued || $isCurrentMultiValued; 123 | } catch (ResourceBundleNotFoundException $e) { 124 | // Continue if there is a fallback locale for the current 125 | // locale 126 | $exception = $e; 127 | } catch (OutOfBoundsException $e) { 128 | // Remember exception and rethrow if we cannot find anything in 129 | // the fallback locales either 130 | $exception = $e; 131 | } 132 | 133 | // Remember which locales we tried 134 | $testedLocales[] = $currentLocale; 135 | 136 | // Check whether fallback is allowed 137 | if (!$fallback) { 138 | break; 139 | } 140 | 141 | // Then determine fallback locale 142 | $currentLocale = Locale::getFallback($currentLocale); 143 | } 144 | 145 | // Multi-valued entry was merged 146 | if ($isMultiValued) { 147 | return $entry; 148 | } 149 | 150 | // Entry is still NULL, but no read error occurred 151 | if ($readSucceeded) { 152 | return $entry; 153 | } 154 | 155 | // Entry is still NULL, read error occurred. Throw an exception 156 | // containing the detailed path and locale 157 | $errorMessage = sprintf( 158 | 'Couldn\'t read the indices [%s] for the locale "%s" in "%s".', 159 | implode('][', $indices), 160 | $locale, 161 | $path 162 | ); 163 | 164 | // Append fallback locales, if any 165 | if (\count($testedLocales) > 1) { 166 | // Remove original locale 167 | array_shift($testedLocales); 168 | 169 | $errorMessage .= sprintf( 170 | ' The indices also couldn\'t be found for the fallback locale(s) "%s".', 171 | implode('", "', $testedLocales) 172 | ); 173 | } 174 | 175 | throw new MissingResourceException($errorMessage, 0, $exception); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Resources/bin/update-data.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Component\Filesystem\Filesystem; 13 | use Symfony\Component\Intl\Data\Bundle\Compiler\GenrbCompiler; 14 | use Symfony\Component\Intl\Data\Bundle\Writer\JsonBundleWriter; 15 | use Symfony\Component\Intl\Data\Generator\CurrencyDataGenerator; 16 | use Symfony\Component\Intl\Data\Generator\GeneratorConfig; 17 | use Symfony\Component\Intl\Data\Generator\LanguageDataGenerator; 18 | use Symfony\Component\Intl\Data\Generator\LocaleDataGenerator; 19 | use Symfony\Component\Intl\Data\Generator\RegionDataGenerator; 20 | use Symfony\Component\Intl\Data\Generator\ScriptDataGenerator; 21 | use Symfony\Component\Intl\Data\Generator\TimezoneDataGenerator; 22 | use Symfony\Component\Intl\Intl; 23 | use Symfony\Component\Intl\Locale; 24 | use Symfony\Component\Intl\Util\GitRepository; 25 | 26 | require_once __DIR__.'/common.php'; 27 | require_once __DIR__.'/autoload.php'; 28 | 29 | $argc = $_SERVER['argc']; 30 | $argv = $_SERVER['argv']; 31 | 32 | if ($argc > 3 || 2 === $argc && '-h' === $argv[1]) { 33 | bailout(<<<'MESSAGE' 34 | Usage: php update-data.php 35 | 36 | Updates the ICU data for Symfony to the latest version of ICU. 37 | 38 | If you downloaded the git repository before, you can pass the path to the 39 | repository source in the first optional argument. 40 | 41 | If you also built the repository before, you can pass the directory where that 42 | build is stored in the second parameter. The build directory needs to contain 43 | the subdirectories bin/ and lib/. 44 | 45 | For running this script, the intl extension must be loaded and all vendors 46 | must have been installed through composer: 47 | 48 | composer install 49 | 50 | MESSAGE 51 | ); 52 | } 53 | 54 | echo LINE; 55 | echo centered('ICU Resource Bundle Compilation')."\n"; 56 | echo LINE; 57 | 58 | if (!Intl::isExtensionLoaded()) { 59 | bailout('The intl extension for PHP is not installed.'); 60 | } 61 | 62 | if ($argc >= 2) { 63 | $repoDir = $argv[1]; 64 | $git = new GitRepository($repoDir); 65 | 66 | echo "Using the existing git repository at {$repoDir}.\n"; 67 | } else { 68 | echo "Starting git clone. This may take a while...\n"; 69 | 70 | $repoDir = sys_get_temp_dir().'/icu-data'; 71 | $git = GitRepository::download('https://github.com/unicode-org/icu.git', $repoDir); 72 | 73 | echo "Git clone to {$repoDir} complete.\n"; 74 | } 75 | 76 | $gitTag = $git->getLastTag(function ($tag) { 77 | return preg_match('#^release-[0-9]{1,}-[0-9]{1}$#', $tag); 78 | }); 79 | $shortIcuVersion = strip_minor_versions(preg_replace('#release-([0-9]{1,})-([0-9]{1,})#', '$1.$2', $gitTag)); 80 | 81 | echo "Checking out `{$gitTag}` for version `{$shortIcuVersion}`...\n"; 82 | $git->checkout('tags/'.$gitTag); 83 | 84 | $filesystem = new Filesystem(); 85 | $sourceDir = $repoDir.'/icu4c/source'; 86 | 87 | if ($argc >= 3) { 88 | $buildDir = $argv[2]; 89 | } else { 90 | // Always build genrb so that we can determine the ICU version of the 91 | // download by running genrb --version 92 | echo "Building genrb.\n"; 93 | 94 | cd($sourceDir); 95 | 96 | echo "Running configure...\n"; 97 | 98 | $buildDir = sys_get_temp_dir().'/icu-data/'.$shortIcuVersion.'/build'; 99 | 100 | $filesystem->remove($buildDir); 101 | $filesystem->mkdir($buildDir); 102 | 103 | run('./configure --prefix='.$buildDir.' 2>&1'); 104 | 105 | echo "Running make...\n"; 106 | 107 | // If the directory "lib" does not exist in the download, create it or we 108 | // will run into problems when building libicuuc.so. 109 | $filesystem->mkdir($sourceDir.'/lib'); 110 | 111 | // If the directory "bin" does not exist in the download, create it or we 112 | // will run into problems when building genrb. 113 | $filesystem->mkdir($sourceDir.'/bin'); 114 | 115 | echo '[1/6] libicudata.so...'; 116 | 117 | cd($sourceDir.'/stubdata'); 118 | run('make 2>&1 && make install 2>&1'); 119 | 120 | echo " ok.\n"; 121 | 122 | echo '[2/6] libicuuc.so...'; 123 | 124 | cd($sourceDir.'/common'); 125 | run('make 2>&1 && make install 2>&1'); 126 | 127 | echo " ok.\n"; 128 | 129 | echo '[3/6] libicui18n.so...'; 130 | 131 | cd($sourceDir.'/i18n'); 132 | run('make 2>&1 && make install 2>&1'); 133 | 134 | echo " ok.\n"; 135 | 136 | echo '[4/6] libicutu.so...'; 137 | 138 | cd($sourceDir.'/tools/toolutil'); 139 | run('make 2>&1 && make install 2>&1'); 140 | 141 | echo " ok.\n"; 142 | 143 | echo '[5/6] libicuio.so...'; 144 | 145 | cd($sourceDir.'/io'); 146 | run('make 2>&1 && make install 2>&1'); 147 | 148 | echo " ok.\n"; 149 | 150 | echo '[6/6] genrb...'; 151 | 152 | cd($sourceDir.'/tools/genrb'); 153 | run('make 2>&1 && make install 2>&1'); 154 | 155 | echo " ok.\n"; 156 | } 157 | 158 | $genrb = $buildDir.'/bin/genrb'; 159 | $genrbEnv = 'LD_LIBRARY_PATH='.$buildDir.'/lib '; 160 | 161 | echo "Using $genrb.\n"; 162 | 163 | $icuVersionInDownload = get_icu_version_from_genrb($genrbEnv.' '.$genrb); 164 | 165 | echo "Preparing resource bundle compilation (version $icuVersionInDownload)...\n"; 166 | 167 | $compiler = new GenrbCompiler($genrb, $genrbEnv); 168 | $config = new GeneratorConfig($sourceDir.'/data', $icuVersionInDownload); 169 | $jsonDir = dirname(__DIR__).'/data'; 170 | 171 | $config->addBundleWriter($jsonDir, new JsonBundleWriter()); 172 | 173 | echo "Starting resource bundle compilation. This may take a while...\n"; 174 | 175 | // We don't want to use fallback to English during generation 176 | Locale::setDefaultFallback('root'); 177 | 178 | echo "Generating language data...\n"; 179 | 180 | $generator = new LanguageDataGenerator($compiler, Intl::LANGUAGE_DIR); 181 | $generator->generateData($config); 182 | 183 | echo "Generating script data...\n"; 184 | 185 | $generator = new ScriptDataGenerator($compiler, Intl::SCRIPT_DIR); 186 | $generator->generateData($config); 187 | 188 | echo "Generating region data...\n"; 189 | 190 | $generator = new RegionDataGenerator($compiler, Intl::REGION_DIR); 191 | $generator->generateData($config); 192 | 193 | echo "Generating currency data...\n"; 194 | 195 | $generator = new CurrencyDataGenerator($compiler, Intl::CURRENCY_DIR); 196 | $generator->generateData($config); 197 | 198 | echo "Generating locale data...\n"; 199 | 200 | $generator = new LocaleDataGenerator($compiler, Intl::LOCALE_DIR); 201 | $generator->generateData($config); 202 | 203 | echo "Generating timezone data...\n"; 204 | 205 | $generator = new TimezoneDataGenerator($compiler, Intl::TIMEZONE_DIR); 206 | $generator->generateData($config); 207 | 208 | echo "Resource bundle compilation complete.\n"; 209 | 210 | $gitInfo = <<getUrl()} 215 | Revision: {$git->getLastCommitHash()} 216 | Author: {$git->getLastAuthor()} 217 | Date: {$git->getLastAuthoredDate()->format('c')} 218 | 219 | GIT_INFO; 220 | 221 | $gitInfoFile = $jsonDir.'/git-info.txt'; 222 | 223 | file_put_contents($gitInfoFile, $gitInfo); 224 | 225 | echo "Wrote $gitInfoFile.\n"; 226 | 227 | $versionFile = $jsonDir.'/version.txt'; 228 | 229 | file_put_contents($versionFile, "$icuVersionInDownload\n"); 230 | 231 | echo "Wrote $versionFile.\n"; 232 | echo "Done.\n"; 233 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/LocaleDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Filesystem\Filesystem; 15 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 16 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 17 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 18 | use Symfony\Component\Intl\Exception\MissingResourceException; 19 | 20 | /** 21 | * The rule for compiling the locale bundle. 22 | * 23 | * @author Bernhard Schussek 24 | * @author Roland Franssen 25 | * 26 | * @internal 27 | */ 28 | class LocaleDataGenerator extends AbstractDataGenerator 29 | { 30 | use FallbackTrait; 31 | 32 | private $locales = []; 33 | private $localeAliases = []; 34 | private $localeParents = []; 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array 40 | { 41 | $this->locales = $scanner->scanLocales($sourceDir.'/locales'); 42 | $this->localeAliases = $scanner->scanAliases($sourceDir.'/locales'); 43 | $this->localeParents = $scanner->scanParents($sourceDir.'/locales'); 44 | 45 | return $this->locales; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir) 52 | { 53 | $filesystem = new Filesystem(); 54 | $filesystem->mkdir([ 55 | $tempDir.'/lang', 56 | $tempDir.'/region', 57 | ]); 58 | $compiler->compile($sourceDir.'/lang', $tempDir.'/lang'); 59 | $compiler->compile($sourceDir.'/region', $tempDir.'/region'); 60 | } 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | protected function preGenerate() 66 | { 67 | // Write parents locale file for the Translation component 68 | file_put_contents( 69 | __DIR__.'/../../../Translation/Resources/data/parents.json', 70 | json_encode($this->localeParents, JSON_PRETTY_PRINT).PHP_EOL 71 | ); 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array 78 | { 79 | // Don't generate aliases, as they are resolved during runtime 80 | // Unless an alias is needed as fallback for de-duplication purposes 81 | if (isset($this->localeAliases[$displayLocale]) && !$this->generatingFallback) { 82 | return null; 83 | } 84 | 85 | // Generate locale names for all locales that have translations in 86 | // at least the language or the region bundle 87 | $displayFormat = $reader->readEntry($tempDir.'/lang', $displayLocale, ['localeDisplayPattern']); 88 | $pattern = $displayFormat['pattern'] ?? '{0} ({1})'; 89 | $separator = $displayFormat['separator'] ?? '{0}, {1}'; 90 | $localeNames = []; 91 | foreach ($this->locales as $locale) { 92 | // Ensure a normalized list of pure locales 93 | if (\Locale::getAllVariants($locale)) { 94 | continue; 95 | } 96 | 97 | try { 98 | // Generate a locale name in the language of each display locale 99 | // Each locale name has the form: "Language (Script, Region, Variant1, ...) 100 | // Script, Region and Variants are optional. If none of them is 101 | // available, the braces are not printed. 102 | $localeNames[$locale] = $this->generateLocaleName($reader, $tempDir, $locale, $displayLocale, $pattern, $separator); 103 | } catch (MissingResourceException $e) { 104 | // Silently ignore incomplete locale names 105 | // In this case one should configure at least one fallback locale that is complete (e.g. English) during 106 | // runtime. Alternatively a translation for the missing resource can be proposed upstream. 107 | } 108 | } 109 | 110 | $data = [ 111 | 'Names' => $localeNames, 112 | ]; 113 | 114 | // Don't de-duplicate a fallback locale 115 | // Ensures the display locale can be de-duplicated on itself 116 | if ($this->generatingFallback) { 117 | return $data; 118 | } 119 | 120 | // Process again to de-duplicate locale and its fallback locales 121 | // Only keep the differences 122 | $fallbackData = $this->generateFallbackData($reader, $tempDir, $displayLocale); 123 | if (isset($fallbackData['Names'])) { 124 | $data['Names'] = array_diff($data['Names'], $fallbackData['Names']); 125 | } 126 | if (!$data['Names']) { 127 | return null; 128 | } 129 | 130 | return $data; 131 | } 132 | 133 | /** 134 | * {@inheritdoc} 135 | */ 136 | protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array 137 | { 138 | return null; 139 | } 140 | 141 | /** 142 | * {@inheritdoc} 143 | */ 144 | protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array 145 | { 146 | return [ 147 | 'Locales' => $this->locales, 148 | 'Aliases' => $this->localeAliases, 149 | ]; 150 | } 151 | 152 | private function generateLocaleName(BundleEntryReaderInterface $reader, string $tempDir, string $locale, string $displayLocale, string $pattern, string $separator): string 153 | { 154 | // Apply generic notation using square brackets as described per http://cldr.unicode.org/translation/language-names 155 | $name = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/lang', $displayLocale, ['Languages', \Locale::getPrimaryLanguage($locale)])); 156 | $extras = []; 157 | 158 | // Discover the name of the script part of the locale 159 | // i.e. in zh_Hans_MO, "Hans" is the script 160 | if ($script = \Locale::getScript($locale)) { 161 | $extras[] = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/lang', $displayLocale, ['Scripts', $script])); 162 | } 163 | 164 | // Discover the name of the region part of the locale 165 | // i.e. in de_AT, "AT" is the region 166 | if ($region = \Locale::getRegion($locale)) { 167 | if (ctype_alpha($region) && !RegionDataGenerator::isValidCountryCode($region)) { 168 | throw new MissingResourceException(sprintf('Skipping "%s" due an invalid country.', $locale)); 169 | } 170 | 171 | $extras[] = str_replace(['(', ')'], ['[', ']'], $reader->readEntry($tempDir.'/region', $displayLocale, ['Countries', $region])); 172 | } 173 | 174 | if ($extras) { 175 | $extra = array_shift($extras); 176 | foreach ($extras as $part) { 177 | $extra = str_replace(['{0}', '{1}'], [$extra, $part], $separator); 178 | } 179 | 180 | $name = str_replace(['{0}', '{1}'], [$name, $extra], $pattern); 181 | } 182 | 183 | return $name; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/RegionDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 15 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 16 | use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle; 17 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 18 | use Symfony\Component\Intl\Exception\RuntimeException; 19 | 20 | /** 21 | * The rule for compiling the region bundle. 22 | * 23 | * @author Bernhard Schussek 24 | * 25 | * @see http://source.icu-project.org/repos/icu/icu4j/trunk/main/classes/core/src/com/ibm/icu/util/Region.java 26 | * 27 | * @internal 28 | */ 29 | class RegionDataGenerator extends AbstractDataGenerator 30 | { 31 | /** 32 | * Source: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes. 33 | */ 34 | private static $preferredAlpha2ToAlpha3Mapping = [ 35 | 'CD' => 'COD', 36 | 'DE' => 'DEU', 37 | 'FR' => 'FRA', 38 | 'MM' => 'MMR', 39 | 'TL' => 'TLS', 40 | 'YE' => 'YEM', 41 | ]; 42 | 43 | private static $blacklist = [ 44 | // Exceptional reservations 45 | 'AC' => true, // Ascension Island 46 | 'CP' => true, // Clipperton Island 47 | 'DG' => true, // Diego Garcia 48 | 'EA' => true, // Ceuta & Melilla 49 | 'EU' => true, // European Union 50 | 'EZ' => true, // Eurozone 51 | 'IC' => true, // Canary Islands 52 | 'TA' => true, // Tristan da Cunha 53 | 'UN' => true, // United Nations 54 | // User-assigned 55 | 'QO' => true, // Outlying Oceania 56 | 'XA' => true, // Pseudo-Accents 57 | 'XB' => true, // Pseudo-Bidi 58 | 'XK' => true, // Kosovo 59 | // Misc 60 | 'ZZ' => true, // Unknown Region 61 | ]; 62 | 63 | /** 64 | * Collects all available language codes. 65 | * 66 | * @var string[] 67 | */ 68 | private $regionCodes = []; 69 | 70 | public static function isValidCountryCode($region) 71 | { 72 | if (isset(self::$blacklist[$region])) { 73 | return false; 74 | } 75 | 76 | // WORLD/CONTINENT/SUBCONTINENT/GROUPING 77 | if (ctype_digit($region) || \is_int($region)) { 78 | return false; 79 | } 80 | 81 | return true; 82 | } 83 | 84 | /** 85 | * {@inheritdoc} 86 | */ 87 | protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array 88 | { 89 | return $scanner->scanLocales($sourceDir.'/region'); 90 | } 91 | 92 | /** 93 | * {@inheritdoc} 94 | */ 95 | protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir) 96 | { 97 | $compiler->compile($sourceDir.'/region', $tempDir); 98 | $compiler->compile($sourceDir.'/misc/metadata.txt', $tempDir); 99 | } 100 | 101 | /** 102 | * {@inheritdoc} 103 | */ 104 | protected function preGenerate() 105 | { 106 | $this->regionCodes = []; 107 | } 108 | 109 | /** 110 | * {@inheritdoc} 111 | */ 112 | protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array 113 | { 114 | $localeBundle = $reader->read($tempDir, $displayLocale); 115 | 116 | // isset() on \ResourceBundle returns true even if the value is null 117 | if (isset($localeBundle['Countries']) && null !== $localeBundle['Countries']) { 118 | $data = [ 119 | 'Names' => $this->generateRegionNames($localeBundle), 120 | ]; 121 | 122 | $this->regionCodes = array_merge($this->regionCodes, array_keys($data['Names'])); 123 | 124 | return $data; 125 | } 126 | 127 | return null; 128 | } 129 | 130 | /** 131 | * {@inheritdoc} 132 | */ 133 | protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array 134 | { 135 | return null; 136 | } 137 | 138 | /** 139 | * {@inheritdoc} 140 | */ 141 | protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array 142 | { 143 | $metadataBundle = $reader->read($tempDir, 'metadata'); 144 | 145 | $this->regionCodes = array_unique($this->regionCodes); 146 | 147 | sort($this->regionCodes); 148 | 149 | $alpha2ToAlpha3 = $this->generateAlpha2ToAlpha3Mapping(array_flip($this->regionCodes), $metadataBundle); 150 | $alpha3ToAlpha2 = array_flip($alpha2ToAlpha3); 151 | asort($alpha3ToAlpha2); 152 | 153 | return [ 154 | 'Regions' => $this->regionCodes, 155 | 'Alpha2ToAlpha3' => $alpha2ToAlpha3, 156 | 'Alpha3ToAlpha2' => $alpha3ToAlpha2, 157 | ]; 158 | } 159 | 160 | protected function generateRegionNames(ArrayAccessibleResourceBundle $localeBundle): array 161 | { 162 | $unfilteredRegionNames = iterator_to_array($localeBundle['Countries']); 163 | $regionNames = []; 164 | 165 | foreach ($unfilteredRegionNames as $region => $regionName) { 166 | if (!self::isValidCountryCode($region)) { 167 | continue; 168 | } 169 | 170 | $regionNames[$region] = $regionName; 171 | } 172 | 173 | return $regionNames; 174 | } 175 | 176 | private function generateAlpha2ToAlpha3Mapping(array $countries, ArrayAccessibleResourceBundle $metadataBundle): array 177 | { 178 | $aliases = iterator_to_array($metadataBundle['alias']['territory']); 179 | $alpha2ToAlpha3 = []; 180 | 181 | foreach ($aliases as $alias => $data) { 182 | $country = $data['replacement']; 183 | if (2 === \strlen($country) && 3 === \strlen($alias) && 'overlong' === $data['reason']) { 184 | if (isset(self::$preferredAlpha2ToAlpha3Mapping[$country])) { 185 | // Validate to prevent typos 186 | if (!isset($aliases[self::$preferredAlpha2ToAlpha3Mapping[$country]])) { 187 | throw new RuntimeException('The statically set three-letter mapping '.self::$preferredAlpha2ToAlpha3Mapping[$country].' for the country code '.$country.' seems to be invalid. Typo?'); 188 | } 189 | 190 | $alpha3 = self::$preferredAlpha2ToAlpha3Mapping[$country]; 191 | $alpha2 = $aliases[$alpha3]['replacement']; 192 | 193 | if ($country !== $alpha2) { 194 | throw new RuntimeException('The statically set three-letter mapping '.$alpha3.' for the country code '.$country.' seems to be an alias for '.$alpha2.'. Wrong mapping?'); 195 | } 196 | 197 | $alpha2ToAlpha3[$country] = $alpha3; 198 | } elseif (isset($alpha2ToAlpha3[$country])) { 199 | throw new RuntimeException('Multiple three-letter mappings exist for the country code '.$country.'. Please add one of them to the property $preferredAlpha2ToAlpha3Mapping.'); 200 | } elseif (isset($countries[$country]) && self::isValidCountryCode($alias)) { 201 | $alpha2ToAlpha3[$country] = $alias; 202 | } 203 | } 204 | } 205 | 206 | asort($alpha2ToAlpha3); 207 | 208 | return $alpha2ToAlpha3; 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Data/Generator/LanguageDataGenerator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Data\Generator; 13 | 14 | use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; 15 | use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; 16 | use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle; 17 | use Symfony\Component\Intl\Data\Util\LocaleScanner; 18 | use Symfony\Component\Intl\Exception\RuntimeException; 19 | 20 | /** 21 | * The rule for compiling the language bundle. 22 | * 23 | * @author Bernhard Schussek 24 | * 25 | * @internal 26 | */ 27 | class LanguageDataGenerator extends AbstractDataGenerator 28 | { 29 | /** 30 | * Source: https://iso639-3.sil.org/code_tables/639/data. 31 | */ 32 | private static $preferredAlpha2ToAlpha3Mapping = [ 33 | 'ak' => 'aka', 34 | 'ar' => 'ara', 35 | 'ay' => 'aym', 36 | 'az' => 'aze', 37 | 'bo' => 'bod', 38 | 'cr' => 'cre', 39 | 'cs' => 'ces', 40 | 'cy' => 'cym', 41 | 'de' => 'deu', 42 | 'dz' => 'dzo', 43 | 'el' => 'ell', 44 | 'et' => 'est', 45 | 'eu' => 'eus', 46 | 'fa' => 'fas', 47 | 'ff' => 'ful', 48 | 'fr' => 'fra', 49 | 'gn' => 'grn', 50 | 'hy' => 'hye', 51 | 'hr' => 'hrv', 52 | 'ik' => 'ipk', 53 | 'is' => 'isl', 54 | 'iu' => 'iku', 55 | 'ka' => 'kat', 56 | 'kr' => 'kau', 57 | 'kg' => 'kon', 58 | 'kv' => 'kom', 59 | 'ku' => 'kur', 60 | 'lv' => 'lav', 61 | 'mg' => 'mlg', 62 | 'mi' => 'mri', 63 | 'mk' => 'mkd', 64 | 'mn' => 'mon', 65 | 'ms' => 'msa', 66 | 'my' => 'mya', 67 | 'nb' => 'nob', 68 | 'ne' => 'nep', 69 | 'nl' => 'nld', 70 | 'oj' => 'oji', 71 | 'om' => 'orm', 72 | 'or' => 'ori', 73 | 'ps' => 'pus', 74 | 'qu' => 'que', 75 | 'ro' => 'ron', 76 | 'sc' => 'srd', 77 | 'sk' => 'slk', 78 | 'sq' => 'sqi', 79 | 'sr' => 'srp', 80 | 'sw' => 'swa', 81 | 'uz' => 'uzb', 82 | 'yi' => 'yid', 83 | 'za' => 'zha', 84 | 'zh' => 'zho', 85 | ]; 86 | private static $blacklist = [ 87 | 'root' => true, // Absolute root language 88 | 'mul' => true, // Multiple languages 89 | 'mis' => true, // Uncoded language 90 | 'und' => true, // Unknown language 91 | 'zxx' => true, // No linguistic content 92 | ]; 93 | 94 | /** 95 | * Collects all available language codes. 96 | * 97 | * @var string[] 98 | */ 99 | private $languageCodes = []; 100 | 101 | /** 102 | * {@inheritdoc} 103 | */ 104 | protected function scanLocales(LocaleScanner $scanner, string $sourceDir): array 105 | { 106 | return $scanner->scanLocales($sourceDir.'/lang'); 107 | } 108 | 109 | /** 110 | * {@inheritdoc} 111 | */ 112 | protected function compileTemporaryBundles(BundleCompilerInterface $compiler, string $sourceDir, string $tempDir) 113 | { 114 | $compiler->compile($sourceDir.'/lang', $tempDir); 115 | $compiler->compile($sourceDir.'/misc/metadata.txt', $tempDir); 116 | } 117 | 118 | /** 119 | * {@inheritdoc} 120 | */ 121 | protected function preGenerate() 122 | { 123 | $this->languageCodes = []; 124 | } 125 | 126 | /** 127 | * {@inheritdoc} 128 | */ 129 | protected function generateDataForLocale(BundleEntryReaderInterface $reader, string $tempDir, string $displayLocale): ?array 130 | { 131 | $localeBundle = $reader->read($tempDir, $displayLocale); 132 | 133 | // isset() on \ResourceBundle returns true even if the value is null 134 | if (isset($localeBundle['Languages']) && null !== $localeBundle['Languages']) { 135 | $names = []; 136 | $localizedNames = []; 137 | foreach (self::generateLanguageNames($localeBundle) as $language => $name) { 138 | if (false === strpos($language, '_')) { 139 | $this->languageCodes[] = $language; 140 | $names[$language] = $name; 141 | } else { 142 | $localizedNames[$language] = $name; 143 | } 144 | } 145 | $data = [ 146 | 'Names' => $names, 147 | 'LocalizedNames' => $localizedNames, 148 | ]; 149 | 150 | return $data; 151 | } 152 | 153 | return null; 154 | } 155 | 156 | /** 157 | * {@inheritdoc} 158 | */ 159 | protected function generateDataForRoot(BundleEntryReaderInterface $reader, string $tempDir): ?array 160 | { 161 | return null; 162 | } 163 | 164 | /** 165 | * {@inheritdoc} 166 | */ 167 | protected function generateDataForMeta(BundleEntryReaderInterface $reader, string $tempDir): ?array 168 | { 169 | $metadataBundle = $reader->read($tempDir, 'metadata'); 170 | 171 | $this->languageCodes = array_unique($this->languageCodes); 172 | 173 | sort($this->languageCodes); 174 | 175 | return [ 176 | 'Languages' => $this->languageCodes, 177 | 'Alpha3Languages' => $this->generateAlpha3Codes($this->languageCodes, $metadataBundle), 178 | 'Alpha2ToAlpha3' => $this->generateAlpha2ToAlpha3Mapping($metadataBundle), 179 | 'Alpha3ToAlpha2' => $this->generateAlpha3ToAlpha2Mapping($metadataBundle), 180 | ]; 181 | } 182 | 183 | private static function generateLanguageNames(ArrayAccessibleResourceBundle $localeBundle): array 184 | { 185 | return array_diff_key(iterator_to_array($localeBundle['Languages']), self::$blacklist); 186 | } 187 | 188 | private function generateAlpha3Codes(array $languageCodes, ArrayAccessibleResourceBundle $metadataBundle): array 189 | { 190 | $alpha3Codes = array_flip(array_filter($languageCodes, static function (string $language): bool { 191 | return 3 === \strlen($language); 192 | })); 193 | 194 | foreach ($metadataBundle['alias']['language'] as $alias => $data) { 195 | if (3 === \strlen($alias) && 'overlong' === $data['reason']) { 196 | $alpha3Codes[$alias] = true; 197 | } 198 | } 199 | 200 | ksort($alpha3Codes); 201 | 202 | return array_keys($alpha3Codes); 203 | } 204 | 205 | private function generateAlpha2ToAlpha3Mapping(ArrayAccessibleResourceBundle $metadataBundle): array 206 | { 207 | $aliases = iterator_to_array($metadataBundle['alias']['language']); 208 | $alpha2ToAlpha3 = []; 209 | 210 | foreach ($aliases as $alias => $data) { 211 | $language = $data['replacement']; 212 | if (2 === \strlen($language) && 3 === \strlen($alias) && 'overlong' === $data['reason']) { 213 | if (isset(self::$preferredAlpha2ToAlpha3Mapping[$language])) { 214 | // Validate to prevent typos 215 | if (!isset($aliases[self::$preferredAlpha2ToAlpha3Mapping[$language]])) { 216 | throw new RuntimeException('The statically set three-letter mapping '.self::$preferredAlpha2ToAlpha3Mapping[$language].' for the language code '.$language.' seems to be invalid. Typo?'); 217 | } 218 | 219 | $alpha3 = self::$preferredAlpha2ToAlpha3Mapping[$language]; 220 | $alpha2 = $aliases[$alpha3]['replacement']; 221 | 222 | if ($language !== $alpha2) { 223 | throw new RuntimeException('The statically set three-letter mapping '.$alpha3.' for the language code '.$language.' seems to be an alias for '.$alpha2.'. Wrong mapping?'); 224 | } 225 | 226 | $alpha2ToAlpha3[$language] = $alpha3; 227 | } elseif (isset($alpha2ToAlpha3[$language])) { 228 | throw new RuntimeException('Multiple three-letter mappings exist for the language code '.$language.'. Please add one of them to the property $preferredAlpha2ToAlpha3Mapping.'); 229 | } else { 230 | $alpha2ToAlpha3[$language] = $alias; 231 | } 232 | } 233 | } 234 | 235 | asort($alpha2ToAlpha3); 236 | 237 | return $alpha2ToAlpha3; 238 | } 239 | 240 | private function generateAlpha3ToAlpha2Mapping(ArrayAccessibleResourceBundle $metadataBundle): array 241 | { 242 | $alpha3ToAlpha2 = []; 243 | 244 | foreach ($metadataBundle['alias']['language'] as $alias => $data) { 245 | $language = $data['replacement']; 246 | if (2 === \strlen($language) && 3 === \strlen($alias) && 'overlong' === $data['reason']) { 247 | $alpha3ToAlpha2[$alias] = $language; 248 | } 249 | } 250 | 251 | asort($alpha3ToAlpha2); 252 | 253 | return $alpha3ToAlpha2; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /vendor/symfony/intl/Collator/Collator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl\Collator; 13 | 14 | use Symfony\Component\Intl\Exception\MethodArgumentValueNotImplementedException; 15 | use Symfony\Component\Intl\Exception\MethodNotImplementedException; 16 | use Symfony\Component\Intl\Globals\IntlGlobals; 17 | use Symfony\Component\Intl\Locale\Locale; 18 | 19 | /** 20 | * Replacement for PHP's native {@link \Collator} class. 21 | * 22 | * The only methods currently supported in this class are: 23 | * 24 | * - {@link \__construct} 25 | * - {@link create} 26 | * - {@link asort} 27 | * - {@link getErrorCode} 28 | * - {@link getErrorMessage} 29 | * - {@link getLocale} 30 | * 31 | * @author Igor Wiedler 32 | * @author Bernhard Schussek 33 | * 34 | * @internal 35 | */ 36 | abstract class Collator 37 | { 38 | /* Attribute constants */ 39 | const FRENCH_COLLATION = 0; 40 | const ALTERNATE_HANDLING = 1; 41 | const CASE_FIRST = 2; 42 | const CASE_LEVEL = 3; 43 | const NORMALIZATION_MODE = 4; 44 | const STRENGTH = 5; 45 | const HIRAGANA_QUATERNARY_MODE = 6; 46 | const NUMERIC_COLLATION = 7; 47 | 48 | /* Attribute constants values */ 49 | const DEFAULT_VALUE = -1; 50 | 51 | const PRIMARY = 0; 52 | const SECONDARY = 1; 53 | const TERTIARY = 2; 54 | const DEFAULT_STRENGTH = 2; 55 | const QUATERNARY = 3; 56 | const IDENTICAL = 15; 57 | 58 | const OFF = 16; 59 | const ON = 17; 60 | 61 | const SHIFTED = 20; 62 | const NON_IGNORABLE = 21; 63 | 64 | const LOWER_FIRST = 24; 65 | const UPPER_FIRST = 25; 66 | 67 | /* Sorting options */ 68 | const SORT_REGULAR = 0; 69 | const SORT_NUMERIC = 2; 70 | const SORT_STRING = 1; 71 | 72 | /** 73 | * @param string|null $locale The locale code. The only currently supported locale is "en" (or null using the default locale, i.e. "en") 74 | * 75 | * @throws MethodArgumentValueNotImplementedException When $locale different than "en" or null is passed 76 | */ 77 | public function __construct(?string $locale) 78 | { 79 | if ('en' !== $locale && null !== $locale) { 80 | throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the locale "en" is supported'); 81 | } 82 | } 83 | 84 | /** 85 | * Static constructor. 86 | * 87 | * @param string|null $locale The locale code. The only currently supported locale is "en" (or null using the default locale, i.e. "en") 88 | * 89 | * @return static 90 | * 91 | * @throws MethodArgumentValueNotImplementedException When $locale different than "en" or null is passed 92 | */ 93 | public static function create(?string $locale) 94 | { 95 | return new static($locale); 96 | } 97 | 98 | /** 99 | * Sort array maintaining index association. 100 | * 101 | * @param array &$array Input array 102 | * @param int $sortFlag Flags for sorting, can be one of the following: 103 | * Collator::SORT_REGULAR - compare items normally (don't change types) 104 | * Collator::SORT_NUMERIC - compare items numerically 105 | * Collator::SORT_STRING - compare items as strings 106 | * 107 | * @return bool True on success or false on failure 108 | */ 109 | public function asort(array &$array, int $sortFlag = self::SORT_REGULAR) 110 | { 111 | $intlToPlainFlagMap = [ 112 | self::SORT_REGULAR => SORT_REGULAR, 113 | self::SORT_NUMERIC => SORT_NUMERIC, 114 | self::SORT_STRING => SORT_STRING, 115 | ]; 116 | 117 | $plainSortFlag = isset($intlToPlainFlagMap[$sortFlag]) ? $intlToPlainFlagMap[$sortFlag] : self::SORT_REGULAR; 118 | 119 | return asort($array, $plainSortFlag); 120 | } 121 | 122 | /** 123 | * Not supported. Compare two Unicode strings. 124 | * 125 | * @param string $str1 The first string to compare 126 | * @param string $str2 The second string to compare 127 | * 128 | * @return bool|int Return the comparison result or false on failure: 129 | * 1 if $str1 is greater than $str2 130 | * 0 if $str1 is equal than $str2 131 | * -1 if $str1 is less than $str2 132 | * 133 | * @see https://php.net/collator.compare 134 | * 135 | * @throws MethodNotImplementedException 136 | */ 137 | public function compare(string $str1, string $str2) 138 | { 139 | throw new MethodNotImplementedException(__METHOD__); 140 | } 141 | 142 | /** 143 | * Not supported. Get a value of an integer collator attribute. 144 | * 145 | * @param int $attr An attribute specifier, one of the attribute constants 146 | * 147 | * @return bool|int The attribute value on success or false on error 148 | * 149 | * @see https://php.net/collator.getattribute 150 | * 151 | * @throws MethodNotImplementedException 152 | */ 153 | public function getAttribute(int $attr) 154 | { 155 | throw new MethodNotImplementedException(__METHOD__); 156 | } 157 | 158 | /** 159 | * Returns collator's last error code. Always returns the U_ZERO_ERROR class constant value. 160 | * 161 | * @return int The error code from last collator call 162 | */ 163 | public function getErrorCode() 164 | { 165 | return IntlGlobals::U_ZERO_ERROR; 166 | } 167 | 168 | /** 169 | * Returns collator's last error message. Always returns the U_ZERO_ERROR_MESSAGE class constant value. 170 | * 171 | * @return string The error message from last collator call 172 | */ 173 | public function getErrorMessage() 174 | { 175 | return 'U_ZERO_ERROR'; 176 | } 177 | 178 | /** 179 | * Returns the collator's locale. 180 | * 181 | * @param int $type Not supported. The locale name type to return (Locale::VALID_LOCALE or Locale::ACTUAL_LOCALE) 182 | * 183 | * @return string The locale used to create the collator. Currently always 184 | * returns "en". 185 | */ 186 | public function getLocale(int $type = Locale::ACTUAL_LOCALE) 187 | { 188 | return 'en'; 189 | } 190 | 191 | /** 192 | * Not supported. Get sorting key for a string. 193 | * 194 | * @param string $string The string to produce the key from 195 | * 196 | * @return string The collation key for $string 197 | * 198 | * @see https://php.net/collator.getsortkey 199 | * 200 | * @throws MethodNotImplementedException 201 | */ 202 | public function getSortKey(string $string) 203 | { 204 | throw new MethodNotImplementedException(__METHOD__); 205 | } 206 | 207 | /** 208 | * Not supported. Get current collator's strength. 209 | * 210 | * @return bool|int The current collator's strength or false on failure 211 | * 212 | * @see https://php.net/collator.getstrength 213 | * 214 | * @throws MethodNotImplementedException 215 | */ 216 | public function getStrength() 217 | { 218 | throw new MethodNotImplementedException(__METHOD__); 219 | } 220 | 221 | /** 222 | * Not supported. Set a collator's attribute. 223 | * 224 | * @param int $attr An attribute specifier, one of the attribute constants 225 | * @param int $val The attribute value, one of the attribute value constants 226 | * 227 | * @return bool True on success or false on failure 228 | * 229 | * @see https://php.net/collator.setattribute 230 | * 231 | * @throws MethodNotImplementedException 232 | */ 233 | public function setAttribute(int $attr, int $val) 234 | { 235 | throw new MethodNotImplementedException(__METHOD__); 236 | } 237 | 238 | /** 239 | * Not supported. Set the collator's strength. 240 | * 241 | * @param int $strength Strength to set, possible values: 242 | * Collator::PRIMARY 243 | * Collator::SECONDARY 244 | * Collator::TERTIARY 245 | * Collator::QUATERNARY 246 | * Collator::IDENTICAL 247 | * Collator::DEFAULT 248 | * 249 | * @return bool True on success or false on failure 250 | * 251 | * @see https://php.net/collator.setstrength 252 | * 253 | * @throws MethodNotImplementedException 254 | */ 255 | public function setStrength(int $strength) 256 | { 257 | throw new MethodNotImplementedException(__METHOD__); 258 | } 259 | 260 | /** 261 | * Not supported. Sort array using specified collator and sort keys. 262 | * 263 | * @param array &$arr Array of strings to sort 264 | * 265 | * @return bool True on success or false on failure 266 | * 267 | * @see https://php.net/collator.sortwithsortkeys 268 | * 269 | * @throws MethodNotImplementedException 270 | */ 271 | public function sortWithSortKeys(array &$arr) 272 | { 273 | throw new MethodNotImplementedException(__METHOD__); 274 | } 275 | 276 | /** 277 | * Not supported. Sort array using specified collator. 278 | * 279 | * @param array &$arr Array of string to sort 280 | * @param int $sortFlag Optional sorting type, one of the following: 281 | * Collator::SORT_REGULAR 282 | * Collator::SORT_NUMERIC 283 | * Collator::SORT_STRING 284 | * 285 | * @return bool True on success or false on failure 286 | * 287 | * @see https://php.net/collator.sort 288 | * 289 | * @throws MethodNotImplementedException 290 | */ 291 | public function sort(array &$arr, int $sortFlag = self::SORT_REGULAR) 292 | { 293 | throw new MethodNotImplementedException(__METHOD__); 294 | } 295 | } 296 | --------------------------------------------------------------------------------